Asterisk - The Open Source Telephony Project  18.5.0
test_cdr.c
Go to the documentation of this file.
1 /*
2  * Asterisk -- An open source telephony toolkit.
3  *
4  * Copyright (C) 2013, Digium, Inc.
5  *
6  * Matt Jordan <[email protected]>
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 <[email protected]>
24  *
25  */
26 
27 /*** MODULEINFO
28  <depend>TEST_FRAMEWORK</depend>
29  <support_level>core</support_level>
30  ***/
31 
32 #include "asterisk.h"
33 
34 #include <math.h>
35 #include "asterisk/module.h"
36 #include "asterisk/test.h"
37 #include "asterisk/cdr.h"
38 #include "asterisk/linkedlists.h"
39 #include "asterisk/chanvars.h"
40 #include "asterisk/utils.h"
41 #include "asterisk/causes.h"
42 #include "asterisk/time.h"
43 #include "asterisk/bridge.h"
44 #include "asterisk/bridge_basic.h"
47 #include "asterisk/format_cache.h"
48 
49 #define EPSILON 0.001
50 
51 #define TEST_CATEGORY "/main/cdr/"
52 
53 #define MOCK_CDR_BACKEND "mock_cdr_backend"
54 
55 #define CHANNEL_TECH_NAME "CDRTestChannel"
56 
57 /*! \brief A placeholder for Asterisk's 'real' CDR configuration */
59 
60 /*! \brief A configuration suitable for 'normal' CDRs */
63 };
64 
65 /*! \brief A configuration suitable for CDRs with unanswered records */
68 };
69 
70 /*! \brief A configuration suitable for CDRs with congestion enabled */
73 };
74 
75 /*! \brief Macro to swap a configuration out from the CDR engine. This should be
76  * used at the beginning of each test to set the needed configuration for that
77  * test.
78  */
79 #define SWAP_CONFIG(ao2_config, template) do { \
80  *(ao2_config) = (template); \
81  ast_cdr_set_config((ao2_config)); \
82  } while (0)
83 
84 /*! \brief A linked list of received CDR entries from the engine */
86 
87 /*! \brief The Mock CDR backend condition wait */
89 
90 /*! \brief A channel technology used for the unit tests */
93  .description = "Mock channel technology for CDR tests",
94 };
95 
97  struct ast_cdr *cdr;
99 };
100 
101 /*! \brief The number of CDRs the mock backend has received */
103 
104 /*! \internal
105  * \brief Callback function for the mock CDR backend
106  *
107  * This function 'processes' a dispatched CDR record by adding it to the
108  * \ref actual_cdr_entries list. When a test completes, it can verify the
109  * expected records against this list of actual CDRs created by the engine.
110  *
111  * \param cdr The public CDR object created by the engine
112  *
113  * \retval -1 on error
114  * \retval 0 on success
115  */
116 static int mock_cdr_backend_cb(struct ast_cdr *cdr)
117 {
118  struct ast_cdr *cdr_copy, *cdr_prev = NULL;
119  struct ast_cdr *mock_cdr = NULL;
120  struct test_cdr_entry *cdr_wrapper;
121 
122  cdr_wrapper = ast_calloc(1, sizeof(*cdr_wrapper));
123  if (!cdr_wrapper) {
124  return -1;
125  }
126 
127  for (; cdr; cdr = cdr->next) {
128  struct ast_var_t *var_entry, *var_copy;
129 
130  cdr_copy = ast_calloc(1, sizeof(*cdr_copy));
131  if (!cdr_copy) {
132  return -1;
133  }
134  *cdr_copy = *cdr;
135  cdr_copy->varshead.first = NULL;
136  cdr_copy->varshead.last = NULL;
137  cdr_copy->next = NULL;
138 
139  AST_LIST_TRAVERSE(&cdr->varshead, var_entry, entries) {
140  var_copy = ast_var_assign(var_entry->name, var_entry->value);
141  if (!var_copy) {
142  return -1;
143  }
144  AST_LIST_INSERT_TAIL(&cdr_copy->varshead, var_copy, entries);
145  }
146 
147  if (!mock_cdr) {
148  mock_cdr = cdr_copy;
149  }
150  if (cdr_prev) {
151  cdr_prev->next = cdr_copy;
152  }
153  cdr_prev = cdr_copy;
154  }
155  cdr_wrapper->cdr = mock_cdr;
156 
162 
163  return 0;
164 }
165 
166 /*! \internal
167  * \brief Remove all entries from \ref actual_cdr_entries
168  */
169 static void clear_mock_cdr_backend(void)
170 {
171  struct test_cdr_entry *cdr_wrapper;
172 
174  while ((cdr_wrapper = AST_LIST_REMOVE_HEAD(&actual_cdr_entries, list))) {
175  ast_cdr_free(cdr_wrapper->cdr);
176  ast_free(cdr_wrapper);
177  }
180 }
181 
182 /*! \brief Verify a string field. This will set the test status result to fail;
183  * as such, it assumes that (a) test is the test object variable, and (b) that
184  * a return variable res exists.
185  */
186 #define VERIFY_STRING_FIELD(field, actual, expected) do { \
187  if (strcmp((actual)->field, (expected)->field)) { \
188  ast_test_status_update(test, "Field %s failed: actual %s, expected %s\n", #field, (actual)->field, (expected)->field); \
189  ast_test_set_result(test, AST_TEST_FAIL); \
190  res = AST_TEST_FAIL; \
191  } } while (0)
192 
193 /*! \brief Verify a numeric field. This will set the test status result to fail;
194  * as such, it assumes that (a) test is the test object variable, and (b) that
195  * a return variable res exists.
196  */
197 #define VERIFY_NUMERIC_FIELD(field, actual, expected) do { \
198  if ((actual)->field != (expected)->field) { \
199  ast_test_status_update(test, "Field %s failed: actual %ld, expected %ld\n", #field, (long)(actual)->field, (long)(expected)->field); \
200  ast_test_set_result(test, AST_TEST_FAIL); \
201  res = AST_TEST_FAIL; \
202  } } while (0)
203 
204 /*! \brief Verify a time field. This will set the test status result to fail;
205  * as such, it assumes that (a) test is the test object variable, and (b) that
206  * a return variable res exists.
207  */
208 #define VERIFY_TIME_VALUE(field, actual) do { \
209  if (ast_tvzero((actual)->field)) { \
210  ast_test_status_update(test, "Field %s failed: should not be 0\n", #field); \
211  ast_test_set_result(test, AST_TEST_FAIL); \
212  res = AST_TEST_FAIL; \
213  } } while (0)
214 
215 /*! \brief Alice's Caller ID */
216 #define ALICE_CALLERID { .id.name.str = "Alice", .id.name.valid = 1, .id.number.str = "100", .id.number.valid = 1, }
217 
218 /*! \brief Bob's Caller ID */
219 #define BOB_CALLERID { .id.name.str = "Bob", .id.name.valid = 1, .id.number.str = "200", .id.number.valid = 1, }
220 
221 /*! \brief Charlie's Caller ID */
222 #define CHARLIE_CALLERID { .id.name.str = "Charlie", .id.name.valid = 1, .id.number.str = "300", .id.number.valid = 1, }
223 
224 /*! \brief David's Caller ID */
225 #define DAVID_CALLERID { .id.name.str = "David", .id.name.valid = 1, .id.number.str = "400", .id.number.valid = 1, }
226 
227 /*! \brief Copy the linkedid and uniqueid from a channel to an expected CDR */
228 #define COPY_IDS(channel_var, expected_record) do { \
229  ast_copy_string((expected_record)->uniqueid, ast_channel_uniqueid((channel_var)), sizeof((expected_record)->uniqueid)); \
230  ast_copy_string((expected_record)->linkedid, ast_channel_linkedid((channel_var)), sizeof((expected_record)->linkedid)); \
231  } while (0)
232 
233 /*! \brief Set ulaw format on channel */
234 #define SET_FORMATS(chan) do {\
235  struct ast_format_cap *caps;\
236  caps = ast_format_cap_alloc(AST_FORMAT_CAP_FLAG_DEFAULT);\
237  ast_format_cap_append(caps, ast_format_ulaw, 0);\
238  ast_channel_nativeformats_set((chan), caps);\
239  ast_channel_set_writeformat((chan), ast_format_ulaw);\
240  ast_channel_set_rawwriteformat((chan), ast_format_ulaw);\
241  ast_channel_set_readformat((chan), ast_format_ulaw);\
242  ast_channel_set_rawreadformat((chan), ast_format_ulaw);\
243  ao2_ref(caps, -1);\
244 } while (0)
245 
246 /*! \brief Create a \ref test_cdr_chan_tech for Alice, and set the expected
247  * CDR records' linkedid and uniqueid. */
248 #define CREATE_ALICE_CHANNEL(channel_var, caller_id, expected_record) do { \
249  (channel_var) = ast_channel_alloc(0, AST_STATE_DOWN, "100", "Alice", "100", "100", "default", NULL, NULL, 0, CHANNEL_TECH_NAME "/Alice"); \
250  SET_FORMATS((channel_var));\
251  ast_channel_set_caller((channel_var), (caller_id), NULL); \
252  ast_copy_string((expected_record)->uniqueid, ast_channel_uniqueid((channel_var)), sizeof((expected_record)->uniqueid)); \
253  ast_copy_string((expected_record)->linkedid, ast_channel_linkedid((channel_var)), sizeof((expected_record)->linkedid)); \
254  ast_channel_unlock((channel_var)); \
255  } while (0)
256 
257 /*! \brief Create a \ref test_cdr_chan_tech for Bob, and set the expected
258  * CDR records' linkedid and uniqueid. */
259 #define CREATE_BOB_CHANNEL(channel_var, caller_id, expected_record) do { \
260  (channel_var) = ast_channel_alloc(0, AST_STATE_DOWN, "200", "Bob", "200", "200", "default", NULL, NULL, 0, CHANNEL_TECH_NAME "/Bob"); \
261  SET_FORMATS((channel_var));\
262  ast_channel_set_caller((channel_var), (caller_id), NULL); \
263  ast_copy_string((expected_record)->uniqueid, ast_channel_uniqueid((channel_var)), sizeof((expected_record)->uniqueid)); \
264  ast_copy_string((expected_record)->linkedid, ast_channel_linkedid((channel_var)), sizeof((expected_record)->linkedid)); \
265  ast_channel_unlock((channel_var)); \
266  } while (0)
267 
268 /*! \brief Create a \ref test_cdr_chan_tech for Charlie, and set the expected
269  * CDR records' linkedid and uniqueid. */
270 #define CREATE_CHARLIE_CHANNEL(channel_var, caller_id, expected_record) do { \
271  (channel_var) = ast_channel_alloc(0, AST_STATE_DOWN, "300", "Charlie", "300", "300", "default", NULL, NULL, 0, CHANNEL_TECH_NAME "/Charlie"); \
272  SET_FORMATS((channel_var));\
273  ast_channel_set_caller((channel_var), (caller_id), NULL); \
274  ast_copy_string((expected_record)->uniqueid, ast_channel_uniqueid((channel_var)), sizeof((expected_record)->uniqueid)); \
275  ast_copy_string((expected_record)->linkedid, ast_channel_linkedid((channel_var)), sizeof((expected_record)->linkedid)); \
276  ast_channel_unlock((channel_var)); \
277  } while (0)
278 
279 /*! \brief Create a \ref test_cdr_chan_tech for Charlie, and set the expected
280  * CDR records' linkedid and uniqueid. */
281 #define CREATE_DAVID_CHANNEL(channel_var, caller_id, expected_record) do { \
282  (channel_var) = ast_channel_alloc(0, AST_STATE_DOWN, "400", "David", "400", "400", "default", NULL, NULL, 0, CHANNEL_TECH_NAME "/David"); \
283  SET_FORMATS((channel_var));\
284  ast_channel_set_caller((channel_var), (caller_id), NULL); \
285  ast_copy_string((expected_record)->uniqueid, ast_channel_uniqueid((channel_var)), sizeof((expected_record)->uniqueid)); \
286  ast_copy_string((expected_record)->linkedid, ast_channel_linkedid((channel_var)), sizeof((expected_record)->linkedid)); \
287  ast_channel_unlock((channel_var)); \
288  } while (0)
289 
290 /*! \brief Emulate a channel entering into an application */
291 #define EMULATE_APP_DATA(channel, priority, application, data) do { \
292  if ((priority) > 0) { \
293  ast_channel_priority_set((channel), (priority)); \
294  } \
295  ast_channel_lock((channel)); \
296  ast_channel_appl_set((channel), (application)); \
297  ast_channel_data_set((channel), (data)); \
298  ast_channel_publish_snapshot((channel)); \
299  ast_channel_unlock((channel)); \
300  } while (0)
301 
302 /*! \brief Hang up a test channel safely */
303 #define HANGUP_CHANNEL(channel, cause) \
304  do { \
305  ast_channel_hangupcause_set((channel), (cause)); \
306  ast_hangup(channel); \
307  channel = NULL; \
308  } while (0)
309 
310 static enum ast_test_result_state verify_mock_cdr_record(struct ast_test *test, struct ast_cdr *expected, int record)
311 {
312  struct ast_cdr *actual = NULL;
313  struct test_cdr_entry *cdr_wrapper;
314  int count = 0;
315  struct timeval wait_now = ast_tvnow();
316  struct timespec wait_time = { .tv_sec = wait_now.tv_sec + 5, .tv_nsec = wait_now.tv_usec * 1000 };
318 
319  while (count < record) {
321  if (global_mock_cdr_count < record) {
323  }
326 
327  if (!cdr_wrapper) {
328  ast_test_status_update(test, "Unable to find actual CDR record at %d\n", count);
329  return AST_TEST_FAIL;
330  }
331  actual = cdr_wrapper->cdr;
332 
333  if (!expected && actual) {
334  ast_test_status_update(test, "CDRs recorded where no record expected\n");
335  return AST_TEST_FAIL;
336  }
337  ast_test_debug(test, "Verifying expected record %s, %s\n",
338  expected->channel, S_OR(expected->dstchannel, "<none>"));
339  VERIFY_STRING_FIELD(accountcode, actual, expected);
340  VERIFY_NUMERIC_FIELD(amaflags, actual, expected);
341  VERIFY_STRING_FIELD(channel, actual, expected);
342  VERIFY_STRING_FIELD(clid, actual, expected);
343  VERIFY_STRING_FIELD(dcontext, actual, expected);
344  VERIFY_NUMERIC_FIELD(disposition, actual, expected);
345  VERIFY_STRING_FIELD(dst, actual, expected);
346  VERIFY_STRING_FIELD(dstchannel, actual, expected);
347  VERIFY_STRING_FIELD(lastapp, actual, expected);
348  VERIFY_STRING_FIELD(lastdata, actual, expected);
349  VERIFY_STRING_FIELD(linkedid, actual, expected);
350  VERIFY_STRING_FIELD(peeraccount, actual, expected);
351  VERIFY_STRING_FIELD(src, actual, expected);
352  VERIFY_STRING_FIELD(uniqueid, actual, expected);
353  VERIFY_STRING_FIELD(userfield, actual, expected);
354  VERIFY_TIME_VALUE(start, actual);
355  VERIFY_TIME_VALUE(end, actual);
356  /* Note: there's no way we can really calculate a duration or
357  * billsec - the unit tests are too short. However, if billsec is
358  * non-zero in the expected, then make sure we have an answer time
359  */
360  if (expected->billsec) {
361  VERIFY_TIME_VALUE(answer, actual);
362  }
363  ast_test_debug(test, "Finished expected record %s, %s\n",
364  expected->channel, S_OR(expected->dstchannel, "<none>"));
365  expected = expected->next;
366  ++count;
367  }
368  return res;
369 }
370 
371 static void safe_channel_release(struct ast_channel *chan)
372 {
373  if (!chan) {
374  return;
375  }
376  ast_channel_release(chan);
377 }
378 
379 static void safe_bridge_destroy(struct ast_bridge *bridge)
380 {
381  if (!bridge) {
382  return;
383  }
384  ast_bridge_destroy(bridge, 0);
385 }
386 
387 static void do_sleep(struct timespec *to_sleep)
388 {
389  while ((nanosleep(to_sleep, to_sleep) == -1) && (errno == EINTR)) {
390  }
391 }
392 
393 AST_TEST_DEFINE(test_cdr_channel_creation)
394 {
395  RAII_VAR(struct ast_channel *, chan, NULL, safe_channel_release);
396  RAII_VAR(struct ast_cdr_config *, config, ao2_alloc(sizeof(*config), NULL),
397  ao2_cleanup);
398 
399  struct ast_party_caller caller = ALICE_CALLERID;
400  struct ast_cdr expected = {
401  .clid = "\"Alice\" <100>",
402  .src = "100",
403  .dst = "100",
404  .dcontext = "default",
405  .channel = CHANNEL_TECH_NAME "/Alice",
406  .amaflags = AST_AMA_DOCUMENTATION,
407  .disposition = AST_CDR_NOANSWER,
408  .accountcode = "100",
409  };
411 
412  switch (cmd) {
413  case TEST_INIT:
414  info->name = __func__;
415  info->category = TEST_CATEGORY;
416  info->summary = "Test that a CDR is created when a channel is created";
417  info->description =
418  "Test that a CDR is created when a channel is created";
419  return AST_TEST_NOT_RUN;
420  case TEST_EXECUTE:
421  break;
422  }
423 
424  SWAP_CONFIG(config, unanswered_cdr_config);
425 
426  CREATE_ALICE_CHANNEL(chan, (&caller), &expected);
427 
429 
430  result = verify_mock_cdr_record(test, &expected, 1);
431 
432  return result;
433 }
434 
435 AST_TEST_DEFINE(test_cdr_unanswered_inbound_call)
436 {
437  RAII_VAR(struct ast_channel *, chan, NULL, safe_channel_release);
438  RAII_VAR(struct ast_cdr_config *, config, ao2_alloc(sizeof(*config), NULL),
439  ao2_cleanup);
440 
441  struct ast_party_caller caller = ALICE_CALLERID;
442  struct ast_cdr expected = {
443  .clid = "\"Alice\" <100>",
444  .src = "100",
445  .dst = "100",
446  .dcontext = "default",
447  .channel = CHANNEL_TECH_NAME "/Alice",
448  .lastapp = "Wait",
449  .lastdata = "1",
450  .amaflags = AST_AMA_DOCUMENTATION,
451  .disposition = AST_CDR_NOANSWER,
452  .accountcode = "100",
453  };
455 
456  switch (cmd) {
457  case TEST_INIT:
458  info->name = __func__;
459  info->category = TEST_CATEGORY;
460  info->summary = "Test inbound unanswered calls";
461  info->description =
462  "Test the properties of a CDR for a call that is\n"
463  "inbound to Asterisk, executes some dialplan, but\n"
464  "is never answered.";
465  return AST_TEST_NOT_RUN;
466  case TEST_EXECUTE:
467  break;
468  }
469 
470  SWAP_CONFIG(config, unanswered_cdr_config);
471 
472  CREATE_ALICE_CHANNEL(chan, &caller, &expected);
473 
474  EMULATE_APP_DATA(chan, 1, "Wait", "1");
475 
477 
478  result = verify_mock_cdr_record(test, &expected, 1);
479 
480  return result;
481 }
482 
483 AST_TEST_DEFINE(test_cdr_unanswered_outbound_call)
484 {
485  RAII_VAR(struct ast_channel *, chan, NULL, safe_channel_release);
486  RAII_VAR(struct ast_cdr_config *, config, ao2_alloc(sizeof(*config), NULL),
487  ao2_cleanup);
488 
489  struct ast_party_caller caller = {
490  .id.name.str = "",
491  .id.name.valid = 1,
492  .id.number.str = "",
493  .id.number.valid = 1, };
494  struct ast_cdr expected = {
495  .clid = "\"\" <>",
496  .dst = "s",
497  .dcontext = "default",
498  .channel = CHANNEL_TECH_NAME "/Alice",
499  .lastapp = "AppDial",
500  .lastdata = "(Outgoing Line)",
501  .amaflags = AST_AMA_DOCUMENTATION,
502  .disposition = AST_CDR_NOANSWER,
503  .accountcode = "100",
504  };
506 
507  switch (cmd) {
508  case TEST_INIT:
509  info->name = __func__;
510  info->category = TEST_CATEGORY;
511  info->summary = "Test outbound unanswered calls";
512  info->description =
513  "Test the properties of a CDR for a call that is\n"
514  "outbound to Asterisk but is never answered.";
515  return AST_TEST_NOT_RUN;
516  case TEST_EXECUTE:
517  break;
518  }
519 
520  SWAP_CONFIG(config, unanswered_cdr_config);
521 
522  CREATE_ALICE_CHANNEL(chan, &caller, &expected);
523 
524  ast_channel_exten_set(chan, "s");
525  ast_channel_context_set(chan, "default");
527  EMULATE_APP_DATA(chan, 0, "AppDial", "(Outgoing Line)");
529 
530  result = verify_mock_cdr_record(test, &expected, 1);
531 
532  return result;
533 }
534 
535 AST_TEST_DEFINE(test_cdr_outbound_bridged_call)
536 {
537  RAII_VAR(struct ast_channel *, chan_alice, NULL, safe_channel_release);
538  RAII_VAR(struct ast_channel *, chan_bob, NULL, safe_channel_release);
539  RAII_VAR(struct ast_bridge *, bridge, NULL, safe_bridge_destroy);
540  RAII_VAR(struct ast_cdr_config *, config, ao2_alloc(sizeof(*config), NULL),
541  ao2_cleanup);
542  struct timespec to_sleep = {1, 0};
544 
545  struct ast_party_caller caller = ALICE_CALLERID;
546  struct ast_cdr alice_expected = {
547  .clid = "\"Alice\" <100>",
548  .src = "100",
549  .dst = "100",
550  .dcontext = "default",
551  .channel = CHANNEL_TECH_NAME "/Alice",
552  .dstchannel = CHANNEL_TECH_NAME "/Bob",
553  .lastapp = "",
554  .lastdata = "",
555  .amaflags = AST_AMA_DOCUMENTATION,
556  .billsec = 1,
557  .disposition = AST_CDR_ANSWERED,
558  .accountcode = "100",
559  .peeraccount = "200",
560  };
561  struct ast_cdr bob_expected = {
562  .clid = "\"\" <>",
563  .src = "",
564  .dst = "s",
565  .dcontext = "default",
566  .channel = CHANNEL_TECH_NAME "/Bob",
567  .dstchannel = "",
568  .lastapp = "AppDial",
569  .lastdata = "(Outgoing Line)",
570  .amaflags = AST_AMA_DOCUMENTATION,
571  .billsec = 1,
572  .disposition = AST_CDR_ANSWERED,
573  .accountcode = "200",
574  .peeraccount = "",
575  .next = &alice_expected,
576  };
577 
578  switch (cmd) {
579  case TEST_INIT:
580  info->name = __func__;
581  info->category = TEST_CATEGORY;
582  info->summary = "Test dialing, answering, and going into a 2-party bridge";
583  info->description =
584  "The most 'basic' of scenarios";
585  return AST_TEST_NOT_RUN;
586  case TEST_EXECUTE:
587  break;
588  }
589 
590  SWAP_CONFIG(config, debug_cdr_config);
591 
592  CREATE_ALICE_CHANNEL(chan_alice, &caller, &alice_expected);
593  ast_channel_state_set(chan_alice, AST_STATE_UP);
594 
595  bridge = ast_bridge_basic_new();
596  ast_test_validate(test, bridge != NULL);
597  do_sleep(&to_sleep);
598 
599  ast_test_validate(test, !ast_bridge_impart(bridge, chan_alice, NULL, NULL, AST_BRIDGE_IMPART_CHAN_DEPARTABLE));
600 
601  chan_bob = ast_channel_alloc(0, AST_STATE_DOWN, NULL, NULL, "200", NULL, NULL, NULL, chan_alice, 0, CHANNEL_TECH_NAME "/Bob");
602  SET_FORMATS(chan_bob);
603  ast_channel_unlock(chan_bob);
604  ast_copy_string(bob_expected.linkedid, ast_channel_linkedid(chan_bob), sizeof(bob_expected.linkedid));
605  ast_copy_string(bob_expected.uniqueid, ast_channel_uniqueid(chan_bob), sizeof(bob_expected.uniqueid));
608  EMULATE_APP_DATA(chan_bob, 0, "AppDial", "(Outgoing Line)");
609 
610  ast_channel_publish_dial(NULL, chan_bob, "Bob", NULL);
612  ast_channel_publish_dial(NULL, chan_bob, NULL, "ANSWER");
613 
615 
616  do_sleep(&to_sleep);
617 
618  ast_test_validate(test, !ast_bridge_impart(bridge, chan_bob, NULL, NULL, AST_BRIDGE_IMPART_CHAN_DEPARTABLE));
619 
620  do_sleep(&to_sleep);
621 
622  ast_bridge_depart(chan_bob);
623  ast_bridge_depart(chan_alice);
624 
625  HANGUP_CHANNEL(chan_bob, AST_CAUSE_NORMAL);
626  HANGUP_CHANNEL(chan_alice, AST_CAUSE_NORMAL);
627 
628  result = verify_mock_cdr_record(test, &bob_expected, 2);
629  return result;
630 }
631 
632 
633 AST_TEST_DEFINE(test_cdr_single_party)
634 {
635  RAII_VAR(struct ast_channel *, chan, NULL, safe_channel_release);
636  RAII_VAR(struct ast_cdr_config *, config, ao2_alloc(sizeof(*config), NULL),
637  ao2_cleanup);
638 
639  struct ast_party_caller caller = ALICE_CALLERID;
640  struct ast_cdr expected = {
641  .clid = "\"Alice\" <100>",
642  .src = "100",
643  .dst = "100",
644  .dcontext = "default",
645  .channel = CHANNEL_TECH_NAME "/Alice",
646  .dstchannel = "",
647  .lastapp = "VoiceMailMain",
648  .lastdata = "1",
649  .billsec = 1,
650  .amaflags = AST_AMA_DOCUMENTATION,
651  .disposition = AST_CDR_ANSWERED,
652  .accountcode = "100",
653  };
655 
656  switch (cmd) {
657  case TEST_INIT:
658  info->name = __func__;
659  info->category = TEST_CATEGORY;
660  info->summary = "Test cdrs for a single party";
661  info->description =
662  "Test the properties of a CDR for a call that is\n"
663  "answered, but only involves a single channel";
664  return AST_TEST_NOT_RUN;
665  case TEST_EXECUTE:
666  break;
667  }
668  SWAP_CONFIG(config, debug_cdr_config);
669  CREATE_ALICE_CHANNEL(chan, &caller, &expected);
670 
671  ast_channel_lock(chan);
672  EMULATE_APP_DATA(chan, 1, "Answer", "");
673  ast_setstate(chan, AST_STATE_UP);
674  EMULATE_APP_DATA(chan, 2, "VoiceMailMain", "1");
675  ast_channel_unlock(chan);
676 
678 
679  result = verify_mock_cdr_record(test, &expected, 1);
680 
681  return result;
682 }
683 
684 AST_TEST_DEFINE(test_cdr_single_bridge)
685 {
686  RAII_VAR(struct ast_channel *, chan, NULL, safe_channel_release);
687  RAII_VAR(struct ast_bridge *, bridge, NULL, safe_bridge_destroy);
688  RAII_VAR(struct ast_cdr_config *, config, ao2_alloc(sizeof(*config), NULL),
689  ao2_cleanup);
690  struct timespec to_sleep = {1, 0};
691 
692  struct ast_party_caller caller = ALICE_CALLERID;
693  struct ast_cdr expected = {
694  .clid = "\"Alice\" <100>",
695  .src = "100",
696  .dst = "100",
697  .dcontext = "default",
698  .channel = CHANNEL_TECH_NAME "/Alice",
699  .lastapp = "Bridge",
700  .billsec = 1,
701  .amaflags = AST_AMA_DOCUMENTATION,
702  .disposition = AST_CDR_ANSWERED,
703  .accountcode = "100",
704  };
706 
707  switch (cmd) {
708  case TEST_INIT:
709  info->name = __func__;
710  info->category = TEST_CATEGORY;
711  info->summary = "Test cdrs for a single party entering/leaving a bridge";
712  info->description =
713  "Test the properties of a CDR for a call that is\n"
714  "answered, enters a bridge, and leaves it.";
715  return AST_TEST_NOT_RUN;
716  case TEST_EXECUTE:
717  break;
718  }
719  SWAP_CONFIG(config, debug_cdr_config);
720  CREATE_ALICE_CHANNEL(chan, &caller, &expected);
721 
722  ast_channel_lock(chan);
723  EMULATE_APP_DATA(chan, 1, "Answer", "");
724  ast_setstate(chan, AST_STATE_UP);
725  EMULATE_APP_DATA(chan, 2, "Bridge", "");
726  ast_channel_unlock(chan);
727 
728  bridge = ast_bridge_basic_new();
729  ast_test_validate(test, bridge != NULL);
730 
731  do_sleep(&to_sleep);
732  ast_test_validate(test, !ast_bridge_impart(bridge, chan, NULL, NULL, AST_BRIDGE_IMPART_CHAN_DEPARTABLE));
733 
734  do_sleep(&to_sleep);
735 
736  ast_bridge_depart(chan);
737 
739 
740  result = verify_mock_cdr_record(test, &expected, 1);
741 
742  return result;
743 }
744 
745 AST_TEST_DEFINE(test_cdr_single_bridge_continue)
746 {
747  RAII_VAR(struct ast_channel *, chan, NULL, safe_channel_release);
748  RAII_VAR(struct ast_bridge *, bridge, NULL, safe_bridge_destroy);
749  RAII_VAR(struct ast_cdr_config *, config, ao2_alloc(sizeof(*config), NULL),
750  ao2_cleanup);
751  struct timespec to_sleep = {1, 0};
752 
753  struct ast_party_caller caller = ALICE_CALLERID;
754  struct ast_cdr expected_two = {
755  .clid = "\"Alice\" <100>",
756  .src = "100",
757  .dst = "100",
758  .dcontext = "default",
759  .channel = CHANNEL_TECH_NAME "/Alice",
760  .lastapp = "Wait",
761  .billsec = 1,
762  .amaflags = AST_AMA_DOCUMENTATION,
763  .disposition = AST_CDR_ANSWERED,
764  .accountcode = "100",
765  };
766  struct ast_cdr expected_one = {
767  .clid = "\"Alice\" <100>",
768  .src = "100",
769  .dst = "100",
770  .dcontext = "default",
771  .channel = CHANNEL_TECH_NAME "/Alice",
772  .lastapp = "Bridge",
773  .billsec = 1,
774  .amaflags = AST_AMA_DOCUMENTATION,
775  .disposition = AST_CDR_ANSWERED,
776  .accountcode = "100",
777  .next = &expected_two,
778  };
779 
781 
782  switch (cmd) {
783  case TEST_INIT:
784  info->name = __func__;
785  info->category = TEST_CATEGORY;
786  info->summary = "Test cdrs for a single party entering/leaving a bridge";
787  info->description =
788  "Test the properties of a CDR for a call that is\n"
789  "answered, enters a bridge, and leaves it.";
790  return AST_TEST_NOT_RUN;
791  case TEST_EXECUTE:
792  break;
793  }
794  SWAP_CONFIG(config, debug_cdr_config);
795  CREATE_ALICE_CHANNEL(chan, &caller, &expected_one);
796  COPY_IDS(chan, &expected_two);
797 
798  ast_channel_lock(chan);
799  EMULATE_APP_DATA(chan, 1, "Answer", "");
800  ast_setstate(chan, AST_STATE_UP);
801  EMULATE_APP_DATA(chan, 2, "Bridge", "");
802  ast_channel_unlock(chan);
803 
804  bridge = ast_bridge_basic_new();
805  ast_test_validate(test, bridge != NULL);
806  do_sleep(&to_sleep);
807 
808  ast_test_validate(test, !ast_bridge_impart(bridge, chan, NULL, NULL, AST_BRIDGE_IMPART_CHAN_DEPARTABLE));
809 
810  do_sleep(&to_sleep);
811 
812  ast_bridge_depart(chan);
813 
814  EMULATE_APP_DATA(chan, 3, "Wait", "");
815 
816  /* And then it hangs up */
818 
819  result = verify_mock_cdr_record(test, &expected_one, 2);
820 
821  return result;
822 }
823 
824 AST_TEST_DEFINE(test_cdr_single_twoparty_bridge_a)
825 {
826  RAII_VAR(struct ast_channel *, chan_alice, NULL, safe_channel_release);
827  RAII_VAR(struct ast_channel *, chan_bob, NULL, safe_channel_release);
828  RAII_VAR(struct ast_bridge *, bridge, NULL, safe_bridge_destroy);
829  RAII_VAR(struct ast_cdr_config *, config, ao2_alloc(sizeof(*config), NULL),
830  ao2_cleanup);
831  struct timespec to_sleep = {1, 0};
832 
833  struct ast_party_caller caller_alice = ALICE_CALLERID;
834  struct ast_party_caller caller_bob = BOB_CALLERID;
835  struct ast_cdr bob_expected = {
836  .clid = "\"Bob\" <200>",
837  .src = "200",
838  .dst = "200",
839  .dcontext = "default",
840  .channel = CHANNEL_TECH_NAME "/Bob",
841  .lastapp = "Bridge",
842  .billsec = 1,
843  .amaflags = AST_AMA_DOCUMENTATION,
844  .disposition = AST_CDR_ANSWERED,
845  .accountcode = "200",
846  };
847  struct ast_cdr alice_expected = {
848  .clid = "\"Alice\" <100>",
849  .src = "100",
850  .dst = "100",
851  .dcontext = "default",
852  .channel = CHANNEL_TECH_NAME "/Alice",
853  .dstchannel = CHANNEL_TECH_NAME "/Bob",
854  .lastapp = "Bridge",
855  .billsec = 1,
856  .amaflags = AST_AMA_DOCUMENTATION,
857  .disposition = AST_CDR_ANSWERED,
858  .accountcode = "100",
859  .peeraccount = "200",
860  .next = &bob_expected,
861  };
862 
864 
865  switch (cmd) {
866  case TEST_INIT:
867  info->name = __func__;
868  info->category = TEST_CATEGORY;
869  info->summary = "Test cdrs for a single party entering/leaving a bridge";
870  info->description =
871  "Test the properties of a CDR for a call that is\n"
872  "answered, enters a bridge, and leaves it. In this scenario, the\n"
873  "Party A should answer the bridge first.";
874  return AST_TEST_NOT_RUN;
875  case TEST_EXECUTE:
876  break;
877  }
878  SWAP_CONFIG(config, debug_cdr_config);
879  CREATE_ALICE_CHANNEL(chan_alice, &caller_alice, &alice_expected);
880 
881  CREATE_BOB_CHANNEL(chan_bob, &caller_bob, &bob_expected);
882  ast_copy_string(bob_expected.linkedid, ast_channel_linkedid(chan_alice), sizeof(bob_expected.linkedid));
883 
884  ast_channel_lock(chan_alice);
885  EMULATE_APP_DATA(chan_alice, 1, "Answer", "");
886  ast_setstate(chan_alice, AST_STATE_UP);
887  EMULATE_APP_DATA(chan_alice, 2, "Bridge", "");
888  ast_channel_unlock(chan_alice);
889 
890  bridge = ast_bridge_basic_new();
891  ast_test_validate(test, bridge != NULL);
892 
893  ast_test_validate(test, !ast_bridge_impart(bridge, chan_alice, NULL, NULL, AST_BRIDGE_IMPART_CHAN_DEPARTABLE));
894  do_sleep(&to_sleep);
895 
896  ast_channel_lock(chan_bob);
897  EMULATE_APP_DATA(chan_bob, 1, "Answer", "");
898  ast_setstate(chan_bob, AST_STATE_UP);
899  EMULATE_APP_DATA(chan_bob, 2, "Bridge", "");
900  ast_channel_unlock(chan_bob);
901 
902  ast_test_validate(test, !ast_bridge_impart(bridge, chan_bob, NULL, NULL, AST_BRIDGE_IMPART_CHAN_DEPARTABLE));
903  do_sleep(&to_sleep);
904 
905  ast_bridge_depart(chan_alice);
906  ast_bridge_depart(chan_bob);
907 
908  HANGUP_CHANNEL(chan_alice, AST_CAUSE_NORMAL);
909  HANGUP_CHANNEL(chan_bob, AST_CAUSE_NORMAL);
910 
911  result = verify_mock_cdr_record(test, &alice_expected, 2);
912 
913  return result;
914 }
915 
916 AST_TEST_DEFINE(test_cdr_single_twoparty_bridge_b)
917 {
918  RAII_VAR(struct ast_channel *, chan_alice, NULL, safe_channel_release);
919  RAII_VAR(struct ast_channel *, chan_bob, NULL, safe_channel_release);
920  RAII_VAR(struct ast_bridge *, bridge, NULL, safe_bridge_destroy);
921  RAII_VAR(struct ast_cdr_config *, config, ao2_alloc(sizeof(*config), NULL),
922  ao2_cleanup);
923  struct timespec to_sleep = {1, 0};
924 
925  struct ast_party_caller caller_alice = ALICE_CALLERID;
926  struct ast_party_caller caller_bob = BOB_CALLERID;
927  struct ast_cdr bob_expected = {
928  .clid = "\"Bob\" <200>",
929  .src = "200",
930  .dst = "200",
931  .dcontext = "default",
932  .channel = CHANNEL_TECH_NAME "/Bob",
933  .lastapp = "Bridge",
934  .billsec = 1,
935  .amaflags = AST_AMA_DOCUMENTATION,
936  .disposition = AST_CDR_ANSWERED,
937  .accountcode = "200",
938  };
939  struct ast_cdr alice_expected = {
940  .clid = "\"Alice\" <100>",
941  .src = "100",
942  .dst = "100",
943  .dcontext = "default",
944  .channel = CHANNEL_TECH_NAME "/Alice",
945  .dstchannel = CHANNEL_TECH_NAME "/Bob",
946  .lastapp = "Bridge",
947  .billsec = 1,
948  .amaflags = AST_AMA_DOCUMENTATION,
949  .disposition = AST_CDR_ANSWERED,
950  .accountcode = "100",
951  .peeraccount = "200",
952  .next = &bob_expected,
953  };
954 
956 
957  switch (cmd) {
958  case TEST_INIT:
959  info->name = __func__;
960  info->category = TEST_CATEGORY;
961  info->summary = "Test cdrs for a single party entering/leaving a bridge";
962  info->description =
963  "Test the properties of a CDR for a call that is\n"
964  "answered, enters a bridge, and leaves it. In this scenario, the\n"
965  "Party B should answer the bridge first.";
966  return AST_TEST_NOT_RUN;
967  case TEST_EXECUTE:
968  break;
969  }
970  SWAP_CONFIG(config, debug_cdr_config);
971  CREATE_ALICE_CHANNEL(chan_alice, &caller_alice, &alice_expected);
972 
973  CREATE_BOB_CHANNEL(chan_bob, &caller_bob, &bob_expected);
974  ast_copy_string(bob_expected.linkedid, ast_channel_linkedid(chan_alice), sizeof(bob_expected.linkedid));
975 
976  ast_channel_unlock(chan_alice);
977  EMULATE_APP_DATA(chan_alice, 1, "Answer", "");
978  ast_setstate(chan_alice, AST_STATE_UP);
979  EMULATE_APP_DATA(chan_alice, 2, "Bridge", "");
980  ast_channel_unlock(chan_alice);
981 
982  bridge = ast_bridge_basic_new();
983  ast_test_validate(test, bridge != NULL);
984 
985  ast_channel_lock(chan_bob);
986  EMULATE_APP_DATA(chan_bob, 1, "Answer", "");
987  ast_setstate(chan_bob, AST_STATE_UP);
988  EMULATE_APP_DATA(chan_bob, 2, "Bridge", "");
989  ast_channel_unlock(chan_bob);
990  do_sleep(&to_sleep);
991 
992  ast_test_validate(test, !ast_bridge_impart(bridge, chan_bob, NULL, NULL, AST_BRIDGE_IMPART_CHAN_DEPARTABLE));
993  do_sleep(&to_sleep);
994 
995  ast_test_validate(test, !ast_bridge_impart(bridge, chan_alice, NULL, NULL, AST_BRIDGE_IMPART_CHAN_DEPARTABLE));
996  do_sleep(&to_sleep);
997 
998  ast_bridge_depart(chan_alice);
999  ast_bridge_depart(chan_bob);
1000 
1001  HANGUP_CHANNEL(chan_alice, AST_CAUSE_NORMAL);
1002  HANGUP_CHANNEL(chan_bob, AST_CAUSE_NORMAL);
1003 
1004  result = verify_mock_cdr_record(test, &alice_expected, 2);
1005 
1006  return result;
1007 }
1008 
1009 AST_TEST_DEFINE(test_cdr_single_multiparty_bridge)
1010 {
1011  RAII_VAR(struct ast_channel *, chan_alice, NULL, safe_channel_release);
1012  RAII_VAR(struct ast_channel *, chan_bob, NULL, safe_channel_release);
1013  RAII_VAR(struct ast_channel *, chan_charlie, NULL, safe_channel_release);
1014  RAII_VAR(struct ast_bridge *, bridge, NULL, safe_bridge_destroy);
1015  RAII_VAR(struct ast_cdr_config *, config, ao2_alloc(sizeof(*config), NULL),
1016  ao2_cleanup);
1017  struct timespec to_sleep = {1, 0};
1018 
1019  struct ast_party_caller caller_alice = ALICE_CALLERID;
1020  struct ast_party_caller caller_bob = BOB_CALLERID;
1021  struct ast_party_caller caller_charlie = CHARLIE_CALLERID;
1022  struct ast_cdr charlie_expected = {
1023  .clid = "\"Charlie\" <300>",
1024  .src = "300",
1025  .dst = "300",
1026  .dcontext = "default",
1027  .channel = CHANNEL_TECH_NAME "/Charlie",
1028  .lastapp = "Bridge",
1029  .billsec = 1,
1030  .amaflags = AST_AMA_DOCUMENTATION,
1031  .disposition = AST_CDR_ANSWERED,
1032  .accountcode = "300",
1033  };
1034  struct ast_cdr bob_expected = {
1035  .clid = "\"Bob\" <200>",
1036  .src = "200",
1037  .dst = "200",
1038  .dcontext = "default",
1039  .channel = CHANNEL_TECH_NAME "/Bob",
1040  .dstchannel = CHANNEL_TECH_NAME "/Charlie",
1041  .lastapp = "Bridge",
1042  .billsec = 1,
1043  .amaflags = AST_AMA_DOCUMENTATION,
1044  .disposition = AST_CDR_ANSWERED,
1045  .accountcode = "200",
1046  .peeraccount = "300",
1047  .next = &charlie_expected,
1048  };
1049  struct ast_cdr alice_expected_two = {
1050  .clid = "\"Alice\" <100>",
1051  .src = "100",
1052  .dst = "100",
1053  .dcontext = "default",
1054  .channel = CHANNEL_TECH_NAME "/Alice",
1055  .dstchannel = CHANNEL_TECH_NAME "/Charlie",
1056  .lastapp = "Bridge",
1057  .billsec = 1,
1058  .amaflags = AST_AMA_DOCUMENTATION,
1059  .disposition = AST_CDR_ANSWERED,
1060  .accountcode = "100",
1061  .peeraccount = "300",
1062  .next = &bob_expected,
1063  };
1064  struct ast_cdr alice_expected_one = {
1065  .clid = "\"Alice\" <100>",
1066  .src = "100",
1067  .dst = "100",
1068  .dcontext = "default",
1069  .channel = CHANNEL_TECH_NAME "/Alice",
1070  .dstchannel = CHANNEL_TECH_NAME "/Bob",
1071  .lastapp = "Bridge",
1072  .billsec = 1,
1073  .amaflags = AST_AMA_DOCUMENTATION,
1074  .disposition = AST_CDR_ANSWERED,
1075  .accountcode = "100",
1076  .peeraccount = "200",
1077  .next = &alice_expected_two,
1078  };
1079 
1081 
1082  switch (cmd) {
1083  case TEST_INIT:
1084  info->name = __func__;
1085  info->category = TEST_CATEGORY;
1086  info->summary = "Test cdrs for a single party entering/leaving a multi-party bridge";
1087  info->description =
1088  "Test the properties of a CDR for a call that is\n"
1089  "answered, enters a bridge, and leaves it. A total of three\n"
1090  "parties perform this action.";
1091  return AST_TEST_NOT_RUN;
1092  case TEST_EXECUTE:
1093  break;
1094  }
1095  SWAP_CONFIG(config, debug_cdr_config);
1096  CREATE_ALICE_CHANNEL(chan_alice, &caller_alice, &alice_expected_one);
1097  COPY_IDS(chan_alice, &alice_expected_two);
1098  CREATE_BOB_CHANNEL(chan_bob, &caller_bob, &bob_expected);
1099  ast_copy_string(bob_expected.linkedid, ast_channel_linkedid(chan_alice), sizeof(bob_expected.linkedid));
1100  CREATE_CHARLIE_CHANNEL(chan_charlie, &caller_charlie, &charlie_expected);
1101  ast_copy_string(charlie_expected.linkedid, ast_channel_linkedid(chan_alice), sizeof(charlie_expected.linkedid));
1102 
1103  ast_channel_lock(chan_alice);
1104  EMULATE_APP_DATA(chan_alice, 1, "Answer", "");
1105  ast_setstate(chan_alice, AST_STATE_UP);
1106  EMULATE_APP_DATA(chan_alice, 2, "Bridge", "");
1107  ast_channel_unlock(chan_alice);
1108 
1109  bridge = ast_bridge_basic_new();
1110  ast_test_validate(test, bridge != NULL);
1111  do_sleep(&to_sleep);
1112 
1113  ast_test_validate(test, !ast_bridge_impart(bridge, chan_alice, NULL, NULL, AST_BRIDGE_IMPART_CHAN_DEPARTABLE));
1114 
1115  ast_channel_lock(chan_bob);
1116  EMULATE_APP_DATA(chan_bob, 1, "Answer", "");
1117  ast_setstate(chan_bob, AST_STATE_UP);
1118  EMULATE_APP_DATA(chan_bob, 2, "Bridge", "");
1119  ast_channel_unlock(chan_bob);
1120  do_sleep(&to_sleep);
1121 
1122  ast_test_validate(test, !ast_bridge_impart(bridge, chan_bob, NULL, NULL, AST_BRIDGE_IMPART_CHAN_DEPARTABLE));
1123 
1124  do_sleep(&to_sleep);
1125 
1126  ast_channel_lock(chan_charlie);
1127  EMULATE_APP_DATA(chan_charlie, 1, "Answer", "");
1128  ast_setstate(chan_charlie, AST_STATE_UP);
1129  EMULATE_APP_DATA(chan_charlie, 2, "Bridge", "");
1130  ast_channel_unlock(chan_charlie);
1131  ast_test_validate(test, !ast_bridge_impart(bridge, chan_charlie, NULL, NULL, AST_BRIDGE_IMPART_CHAN_DEPARTABLE));
1132 
1133  do_sleep(&to_sleep);
1134 
1135  ast_bridge_depart(chan_alice);
1136  ast_bridge_depart(chan_bob);
1137  ast_bridge_depart(chan_charlie);
1138 
1139  HANGUP_CHANNEL(chan_alice, AST_CAUSE_NORMAL);
1140  HANGUP_CHANNEL(chan_bob, AST_CAUSE_NORMAL);
1141  HANGUP_CHANNEL(chan_charlie, AST_CAUSE_NORMAL);
1142 
1143  result = verify_mock_cdr_record(test, &alice_expected_one, 4);
1144 
1145  return result;
1146 }
1147 
1148 AST_TEST_DEFINE(test_cdr_dial_unanswered)
1149 {
1150  RAII_VAR(struct ast_channel *, chan_caller, NULL, safe_channel_release);
1151  RAII_VAR(struct ast_channel *, chan_callee, NULL, safe_channel_release);
1152  RAII_VAR(struct ast_cdr_config *, config, ao2_alloc(sizeof(*config), NULL),
1153  ao2_cleanup);
1154 
1155  struct ast_party_caller caller = ALICE_CALLERID;
1156  struct ast_cdr expected = {
1157  .clid = "\"Alice\" <100>",
1158  .src = "100",
1159  .dst = "100",
1160  .dcontext = "default",
1161  .channel = CHANNEL_TECH_NAME "/Alice",
1162  .dstchannel = CHANNEL_TECH_NAME "/Bob",
1163  .lastapp = "Dial",
1164  .lastdata = CHANNEL_TECH_NAME "/Bob",
1165  .billsec = 0,
1166  .amaflags = AST_AMA_DOCUMENTATION,
1167  .disposition = AST_CDR_NOANSWER,
1168  .accountcode = "100",
1169  .peeraccount = "200",
1170  };
1172 
1173  switch (cmd) {
1174  case TEST_INIT:
1175  info->name = __func__;
1176  info->category = TEST_CATEGORY;
1177  info->summary = "Test CDRs for a dial that isn't answered";
1178  info->description =
1179  "Test the properties of a CDR for a channel that\n"
1180  "performs a dial operation that isn't answered";
1181  return AST_TEST_NOT_RUN;
1182  case TEST_EXECUTE:
1183  break;
1184  }
1185 
1186  SWAP_CONFIG(config, unanswered_cdr_config);
1187 
1188  CREATE_ALICE_CHANNEL(chan_caller, &caller, &expected);
1189 
1190  EMULATE_APP_DATA(chan_caller, 1, "Dial", "CDRTestChannel/Bob");
1191 
1192  chan_callee = ast_channel_alloc(0, AST_STATE_DOWN, NULL, NULL, "200", NULL, NULL, NULL, chan_caller, 0, CHANNEL_TECH_NAME "/Bob");
1193  SET_FORMATS(chan_callee);
1194  ast_channel_unlock(chan_callee);
1196  EMULATE_APP_DATA(chan_callee, 0, "AppDial", "(Outgoing Line)");
1197 
1198  ast_channel_publish_dial(chan_caller, chan_callee, "Bob", NULL);
1200  ast_channel_publish_dial(chan_caller, chan_callee, NULL, "NOANSWER");
1201 
1202  HANGUP_CHANNEL(chan_caller, AST_CAUSE_NO_ANSWER);
1203  HANGUP_CHANNEL(chan_callee, AST_CAUSE_NO_ANSWER);
1204 
1205  result = verify_mock_cdr_record(test, &expected, 1);
1206 
1207  return result;
1208 }
1209 
1210 
1211 AST_TEST_DEFINE(test_cdr_dial_busy)
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_BUSY,
1231  .accountcode = "100",
1232  .peeraccount = "200",
1233  };
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 a busy";
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 busy";
1244  return AST_TEST_NOT_RUN;
1245  case TEST_EXECUTE:
1246  break;
1247  }
1248 
1249  SWAP_CONFIG(config, unanswered_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, NULL, chan_caller, 0, CHANNEL_TECH_NAME "/Bob");
1256  SET_FORMATS(chan_callee);
1257  ast_channel_unlock(chan_callee);
1259  EMULATE_APP_DATA(chan_callee, 0, "AppDial", "(Outgoing Line)");
1260 
1261  ast_channel_publish_dial(chan_caller, chan_callee, "Bob", NULL);
1263  ast_channel_publish_dial(chan_caller, chan_callee, NULL, "BUSY");
1264 
1265  HANGUP_CHANNEL(chan_caller, AST_CAUSE_BUSY);
1266  HANGUP_CHANNEL(chan_callee, AST_CAUSE_BUSY);
1267 
1268  result = verify_mock_cdr_record(test, &expected, 1);
1269 
1270  return result;
1271 }
1272 
1273 AST_TEST_DEFINE(test_cdr_dial_congestion)
1274 {
1275  RAII_VAR(struct ast_channel *, chan_caller, NULL, safe_channel_release);
1276  RAII_VAR(struct ast_channel *, chan_callee, NULL, safe_channel_release);
1277  RAII_VAR(struct ast_cdr_config *, config, ao2_alloc(sizeof(*config), NULL),
1278  ao2_cleanup);
1279 
1280  struct ast_party_caller caller = ALICE_CALLERID;
1281  struct ast_cdr expected = {
1282  .clid = "\"Alice\" <100>",
1283  .src = "100",
1284  .dst = "100",
1285  .dcontext = "default",
1286  .channel = CHANNEL_TECH_NAME "/Alice",
1287  .dstchannel = CHANNEL_TECH_NAME "/Bob",
1288  .lastapp = "Dial",
1289  .lastdata = CHANNEL_TECH_NAME "/Bob",
1290  .billsec = 0,
1291  .amaflags = AST_AMA_DOCUMENTATION,
1292  .disposition = AST_CDR_CONGESTION,
1293  .accountcode = "100",
1294  .peeraccount = "200",
1295  };
1297 
1298  switch (cmd) {
1299  case TEST_INIT:
1300  info->name = __func__;
1301  info->category = TEST_CATEGORY;
1302  info->summary = "Test CDRs for a dial that results in congestion";
1303  info->description =
1304  "Test the properties of a CDR for a channel that\n"
1305  "performs a dial operation to an endpoint that's congested";
1306  return AST_TEST_NOT_RUN;
1307  case TEST_EXECUTE:
1308  break;
1309  }
1310 
1311  SWAP_CONFIG(config, congestion_cdr_config);
1312 
1313  CREATE_ALICE_CHANNEL(chan_caller, &caller, &expected);
1314 
1315  EMULATE_APP_DATA(chan_caller, 1, "Dial", CHANNEL_TECH_NAME "/Bob");
1316 
1317  chan_callee = ast_channel_alloc(0, AST_STATE_DOWN, NULL, NULL, "200", NULL, NULL, NULL, chan_caller, 0, CHANNEL_TECH_NAME "/Bob");
1318  SET_FORMATS(chan_callee);
1319  ast_channel_unlock(chan_callee);
1321  EMULATE_APP_DATA(chan_callee, 0, "AppDial", "(Outgoing Line)");
1322 
1323  ast_channel_publish_dial(chan_caller, chan_callee, "Bob", NULL);
1325  ast_channel_publish_dial(chan_caller, chan_callee, NULL, "CONGESTION");
1326 
1327  HANGUP_CHANNEL(chan_caller, AST_CAUSE_CONGESTION);
1328  HANGUP_CHANNEL(chan_callee, AST_CAUSE_CONGESTION);
1329 
1330  result = verify_mock_cdr_record(test, &expected, 1);
1331 
1332  return result;
1333 }
1334 
1335 AST_TEST_DEFINE(test_cdr_dial_unavailable)
1336 {
1337  RAII_VAR(struct ast_channel *, chan_caller, NULL, safe_channel_release);
1338  RAII_VAR(struct ast_channel *, chan_callee, NULL, safe_channel_release);
1339  RAII_VAR(struct ast_cdr_config *, config, ao2_alloc(sizeof(*config), NULL),
1340  ao2_cleanup);
1341 
1342  struct ast_party_caller caller = ALICE_CALLERID;
1343  struct ast_cdr expected = {
1344  .clid = "\"Alice\" <100>",
1345  .src = "100",
1346  .dst = "100",
1347  .dcontext = "default",
1348  .channel = CHANNEL_TECH_NAME "/Alice",
1349  .dstchannel = CHANNEL_TECH_NAME "/Bob",
1350  .lastapp = "Dial",
1351  .lastdata = CHANNEL_TECH_NAME "/Bob",
1352  .billsec = 0,
1353  .amaflags = AST_AMA_DOCUMENTATION,
1354  .disposition = AST_CDR_FAILED,
1355  .accountcode = "100",
1356  .peeraccount = "200",
1357  };
1359 
1360  switch (cmd) {
1361  case TEST_INIT:
1362  info->name = __func__;
1363  info->category = TEST_CATEGORY;
1364  info->summary = "Test CDRs for a dial that results in unavailable";
1365  info->description =
1366  "Test the properties of a CDR for a channel that\n"
1367  "performs a dial operation to an endpoint that's unavailable";
1368  return AST_TEST_NOT_RUN;
1369  case TEST_EXECUTE:
1370  break;
1371  }
1372 
1373  SWAP_CONFIG(config, unanswered_cdr_config);
1374 
1375  CREATE_ALICE_CHANNEL(chan_caller, &caller, &expected);
1376 
1377  EMULATE_APP_DATA(chan_caller, 1, "Dial", CHANNEL_TECH_NAME "/Bob");
1378 
1379  chan_callee = ast_channel_alloc(0, AST_STATE_DOWN, NULL, NULL, "200", NULL, NULL, NULL, chan_caller, 0, CHANNEL_TECH_NAME "/Bob");
1380  SET_FORMATS(chan_callee);
1381  ast_channel_unlock(chan_callee);
1383  EMULATE_APP_DATA(chan_callee, 0, "AppDial", "(Outgoing Line)");
1384 
1385  ast_channel_publish_dial(chan_caller, chan_callee, "Bob", NULL);
1387  ast_channel_publish_dial(chan_caller, chan_callee, NULL, "CHANUNAVAIL");
1388 
1391 
1392  result = verify_mock_cdr_record(test, &expected, 1);
1393 
1394  return result;
1395 }
1396 
1397 AST_TEST_DEFINE(test_cdr_dial_caller_cancel)
1398 {
1399  RAII_VAR(struct ast_channel *, chan_caller, NULL, safe_channel_release);
1400  RAII_VAR(struct ast_channel *, chan_callee, NULL, safe_channel_release);
1401  RAII_VAR(struct ast_cdr_config *, config, ao2_alloc(sizeof(*config), NULL),
1402  ao2_cleanup);
1403 
1404  struct ast_party_caller caller = ALICE_CALLERID;
1405  struct ast_cdr expected = {
1406  .clid = "\"Alice\" <100>",
1407  .src = "100",
1408  .dst = "100",
1409  .dcontext = "default",
1410  .channel = CHANNEL_TECH_NAME "/Alice",
1411  .dstchannel = CHANNEL_TECH_NAME "/Bob",
1412  .lastapp = "Dial",
1413  .lastdata = CHANNEL_TECH_NAME "/Bob",
1414  .billsec = 0,
1415  .amaflags = AST_AMA_DOCUMENTATION,
1416  .disposition = AST_CDR_NOANSWER,
1417  .accountcode = "100",
1418  .peeraccount = "200",
1419  };
1421 
1422  switch (cmd) {
1423  case TEST_INIT:
1424  info->name = __func__;
1425  info->category = TEST_CATEGORY;
1426  info->summary = "Test CDRs for a dial where the caller cancels";
1427  info->description =
1428  "Test the properties of a CDR for a channel that\n"
1429  "performs a dial operation to an endpoint but then decides\n"
1430  "to hang up, cancelling the dial";
1431  return AST_TEST_NOT_RUN;
1432  case TEST_EXECUTE:
1433  break;
1434  }
1435 
1436  SWAP_CONFIG(config, unanswered_cdr_config);
1437 
1438  CREATE_ALICE_CHANNEL(chan_caller, &caller, &expected);
1439 
1440  EMULATE_APP_DATA(chan_caller, 1, "Dial", CHANNEL_TECH_NAME "/Bob");
1441 
1442  chan_callee = ast_channel_alloc(0, AST_STATE_DOWN, NULL, NULL, "200", NULL, NULL, NULL, chan_caller, 0, CHANNEL_TECH_NAME "/Bob");
1443  SET_FORMATS(chan_callee);
1444  ast_channel_unlock(chan_callee);
1446  EMULATE_APP_DATA(chan_callee, 0, "AppDial", "(Outgoing Line)");
1447 
1448  ast_channel_publish_dial(chan_caller, chan_callee, "Bob", NULL);
1450  ast_channel_publish_dial(chan_caller, chan_callee, NULL, "CANCEL");
1451 
1452  HANGUP_CHANNEL(chan_callee, AST_CAUSE_NORMAL);
1453  HANGUP_CHANNEL(chan_caller, AST_CAUSE_NORMAL);
1454 
1455  result = verify_mock_cdr_record(test, &expected, 1);
1456 
1457  return result;
1458 }
1459 
1460 AST_TEST_DEFINE(test_cdr_dial_parallel_failed)
1461 {
1462  RAII_VAR(struct ast_channel *, chan_caller, NULL, safe_channel_release);
1463  RAII_VAR(struct ast_channel *, chan_bob, NULL, safe_channel_release);
1464  RAII_VAR(struct ast_channel *, chan_charlie, NULL, safe_channel_release);
1465  RAII_VAR(struct ast_channel *, chan_david, NULL, safe_channel_release);
1466  RAII_VAR(struct ast_cdr_config *, config, ao2_alloc(sizeof(*config), NULL),
1467  ao2_cleanup);
1468 
1469  struct ast_party_caller caller = ALICE_CALLERID;
1470  struct ast_cdr bob_expected = {
1471  .clid = "\"Alice\" <100>",
1472  .src = "100",
1473  .dst = "100",
1474  .dcontext = "default",
1475  .channel = CHANNEL_TECH_NAME "/Alice",
1476  .dstchannel = CHANNEL_TECH_NAME "/Bob",
1477  .lastapp = "Dial",
1478  .lastdata = CHANNEL_TECH_NAME "/Bob&" CHANNEL_TECH_NAME "/Charlie&" CHANNEL_TECH_NAME "/David",
1479  .billsec = 0,
1480  .amaflags = AST_AMA_DOCUMENTATION,
1481  .disposition = AST_CDR_NOANSWER,
1482  .accountcode = "100",
1483  .peeraccount = "200",
1484  };
1485  struct ast_cdr charlie_expected = {
1486  .clid = "\"Alice\" <100>",
1487  .src = "100",
1488  .dst = "100",
1489  .dcontext = "default",
1490  .channel = CHANNEL_TECH_NAME "/Alice",
1491  .dstchannel = CHANNEL_TECH_NAME "/Charlie",
1492  .lastapp = "Dial",
1493  .lastdata = CHANNEL_TECH_NAME "/Bob&" CHANNEL_TECH_NAME "/Charlie&" CHANNEL_TECH_NAME "/David",
1494  .billsec = 0,
1495  .amaflags = AST_AMA_DOCUMENTATION,
1496  .disposition = AST_CDR_BUSY,
1497  .accountcode = "100",
1498  .peeraccount = "300",
1499  };
1500  struct ast_cdr david_expected = {
1501  .clid = "\"Alice\" <100>",
1502  .src = "100",
1503  .dst = "100",
1504  .dcontext = "default",
1505  .channel = CHANNEL_TECH_NAME "/Alice",
1506  .dstchannel = CHANNEL_TECH_NAME "/David",
1507  .lastapp = "Dial",
1508  .lastdata = CHANNEL_TECH_NAME "/Bob&" CHANNEL_TECH_NAME "/Charlie&" CHANNEL_TECH_NAME "/David",
1509  .billsec = 0,
1510  .amaflags = AST_AMA_DOCUMENTATION,
1511  .disposition = AST_CDR_CONGESTION,
1512  .accountcode = "100",
1513  .peeraccount = "400",
1514  };
1516 
1517  struct ast_cdr *expected = &bob_expected;
1518  bob_expected.next = &charlie_expected;
1519  charlie_expected.next = &david_expected;
1520 
1521  switch (cmd) {
1522  case TEST_INIT:
1523  info->name = __func__;
1524  info->category = TEST_CATEGORY;
1525  info->summary = "Test a parallel dial where all channels fail to answer";
1526  info->description =
1527  "This tests dialing three parties: Bob, Charlie, David. Charlie\n"
1528  "returns BUSY; David returns CONGESTION; Bob fails to answer and\n"
1529  "Alice hangs up. Three records are created for Alice as a result.";
1530  return AST_TEST_NOT_RUN;
1531  case TEST_EXECUTE:
1532  break;
1533  }
1534 
1535  SWAP_CONFIG(config, congestion_cdr_config);
1536 
1537  CREATE_ALICE_CHANNEL(chan_caller, &caller, &bob_expected);
1538  COPY_IDS(chan_caller, &charlie_expected);
1539  COPY_IDS(chan_caller, &david_expected);
1540 
1541  /* Channel enters Dial app */
1542  EMULATE_APP_DATA(chan_caller, 1, "Dial", CHANNEL_TECH_NAME "/Bob&" CHANNEL_TECH_NAME "/Charlie&" CHANNEL_TECH_NAME "/David");
1543 
1544  /* Outbound channels are created */
1545  chan_bob = ast_channel_alloc(0, AST_STATE_DOWN, NULL, NULL, "200", NULL, NULL, NULL, chan_caller, 0, CHANNEL_TECH_NAME "/Bob");
1546  SET_FORMATS(chan_bob);
1547  ast_channel_unlock(chan_bob);
1549  EMULATE_APP_DATA(chan_bob, 0, "AppDial", "(Outgoing Line)");
1550 
1551  chan_charlie = ast_channel_alloc(0, AST_STATE_DOWN, NULL, NULL, "300", NULL, NULL, NULL, chan_caller, 0, CHANNEL_TECH_NAME "/Charlie");
1552  SET_FORMATS(chan_charlie);
1553  ast_channel_unlock(chan_charlie);
1555  EMULATE_APP_DATA(chan_charlie, 0, "AppDial", "(Outgoing Line)");
1556 
1557  chan_david = ast_channel_alloc(0, AST_STATE_DOWN, NULL, NULL, "400", NULL, NULL, NULL, chan_caller, 0, CHANNEL_TECH_NAME "/David");
1558  SET_FORMATS(chan_charlie);
1559  ast_channel_unlock(chan_david);
1561  EMULATE_APP_DATA(chan_david, 0, "AppDial", "(Outgoing Line)");
1562 
1563  /* Dial starts */
1564  ast_channel_publish_dial(chan_caller, chan_bob, "Bob", NULL);
1565  ast_channel_publish_dial(chan_caller, chan_charlie, "Charlie", NULL);
1566  ast_channel_publish_dial(chan_caller, chan_david, "David", NULL);
1568 
1569  /* Charlie is busy */
1570  ast_channel_publish_dial(chan_caller, chan_charlie, NULL, "BUSY");
1571  HANGUP_CHANNEL(chan_charlie, AST_CAUSE_BUSY);
1572 
1573  /* David is congested */
1574  ast_channel_publish_dial(chan_caller, chan_david, NULL, "CONGESTION");
1575  HANGUP_CHANNEL(chan_david, AST_CAUSE_CONGESTION);
1576 
1577  /* Bob is canceled */
1578  ast_channel_publish_dial(chan_caller, chan_bob, NULL, "CANCEL");
1579  HANGUP_CHANNEL(chan_bob, AST_CAUSE_NORMAL);
1580 
1581  /* Alice hangs up */
1582  HANGUP_CHANNEL(chan_caller, AST_CAUSE_NORMAL);
1583 
1584  result = verify_mock_cdr_record(test, expected, 3);
1585 
1586  return result;
1587 }
1588 
1589 AST_TEST_DEFINE(test_cdr_dial_answer_no_bridge)
1590 {
1591  RAII_VAR(struct ast_channel *, chan_caller, NULL, safe_channel_release);
1592  RAII_VAR(struct ast_channel *, chan_callee, NULL, safe_channel_release);
1593  RAII_VAR(struct ast_cdr_config *, config, ao2_alloc(sizeof(*config), NULL),
1594  ao2_cleanup);
1595 
1596  struct ast_party_caller caller = ALICE_CALLERID;
1597  struct ast_cdr bob_expected_one = {
1598  .clid = "\"\" <>",
1599  .src = "",
1600  .dst = "s",
1601  .dcontext = "default",
1602  .channel = CHANNEL_TECH_NAME "/Bob",
1603  .lastapp = "Wait",
1604  .lastdata = "1",
1605  .amaflags = AST_AMA_DOCUMENTATION,
1606  .disposition = AST_CDR_ANSWERED,
1607  .accountcode = "200",
1608  };
1609  struct ast_cdr alice_expected_two = {
1610  .clid = "\"Alice\" <100>",
1611  .src = "100",
1612  .dst = "100",
1613  .dcontext = "default",
1614  .channel = CHANNEL_TECH_NAME "/Alice",
1615  .lastapp = "Wait",
1616  .lastdata = "1",
1617  .amaflags = AST_AMA_DOCUMENTATION,
1618  .disposition = AST_CDR_ANSWERED,
1619  .accountcode = "100",
1620  .next = &bob_expected_one,
1621  };
1622  struct ast_cdr alice_expected_one = {
1623  .clid = "\"Alice\" <100>",
1624  .src = "100",
1625  .dst = "100",
1626  .dcontext = "default",
1627  .channel = CHANNEL_TECH_NAME "/Alice",
1628  .dstchannel = CHANNEL_TECH_NAME "/Bob",
1629  .lastapp = "Dial",
1630  .lastdata = CHANNEL_TECH_NAME "/Bob",
1631  .amaflags = AST_AMA_DOCUMENTATION,
1632  .disposition = AST_CDR_ANSWERED,
1633  .accountcode = "100",
1634  .peeraccount = "200",
1635  .next = &alice_expected_two,
1636  };
1638 
1639  switch (cmd) {
1640  case TEST_INIT:
1641  info->name = __func__;
1642  info->category = TEST_CATEGORY;
1643  info->summary = "Test dialing, answering, and not going into a bridge.";
1644  info->description =
1645  "This is a weird one, but theoretically possible. You can perform\n"
1646  "a dial, then bounce both channels to different priorities and\n"
1647  "never have them enter a bridge together. Ew. This makes sure that\n"
1648  "when we answer, we get a CDR, it gets ended at that point, and\n"
1649  "that it gets finalized appropriately. We should get three CDRs in\n"
1650  "the end - one for the dial, and one for each CDR as they continued\n"
1651  "on.";
1652  return AST_TEST_NOT_RUN;
1653  case TEST_EXECUTE:
1654  break;
1655  }
1656 
1657  SWAP_CONFIG(config, debug_cdr_config);
1658 
1659  CREATE_ALICE_CHANNEL(chan_caller, &caller, &alice_expected_one);
1660  COPY_IDS(chan_caller, &alice_expected_two);
1661 
1662  EMULATE_APP_DATA(chan_caller, 1, "Dial", CHANNEL_TECH_NAME "/Bob");
1663 
1664  chan_callee = ast_channel_alloc(0, AST_STATE_DOWN, NULL, NULL, "200", NULL, NULL, NULL, chan_caller, 0, CHANNEL_TECH_NAME "/Bob");
1665  SET_FORMATS(chan_callee);
1666  ast_channel_unlock(chan_callee);
1668  COPY_IDS(chan_callee, &bob_expected_one);
1669 
1670  ast_channel_publish_dial(chan_caller, chan_callee, "Bob", NULL);
1672  ast_channel_publish_dial(chan_caller, chan_callee, NULL, "ANSWER");
1673 
1674  ast_channel_state_set(chan_caller, AST_STATE_UP);
1676  ast_channel_state_set(chan_callee, AST_STATE_UP);
1677 
1678  EMULATE_APP_DATA(chan_caller, 2, "Wait", "1");
1679  EMULATE_APP_DATA(chan_callee, 1, "Wait", "1");
1680 
1681  HANGUP_CHANNEL(chan_caller, AST_CAUSE_NORMAL);
1682  HANGUP_CHANNEL(chan_callee, AST_CAUSE_NORMAL);
1683 
1684  result = verify_mock_cdr_record(test, &alice_expected_one, 3);
1685  return result;
1686 }
1687 
1688 AST_TEST_DEFINE(test_cdr_dial_answer_twoparty_bridge_a)
1689 {
1690  RAII_VAR(struct ast_channel *, chan_caller, NULL, safe_channel_release);
1691  RAII_VAR(struct ast_channel *, chan_callee, NULL, safe_channel_release);
1692  RAII_VAR(struct ast_bridge *, bridge, NULL, safe_bridge_destroy);
1693  RAII_VAR(struct ast_cdr_config *, config, ao2_alloc(sizeof(*config), NULL),
1694  ao2_cleanup);
1695  struct timespec to_sleep = {1, 0};
1697 
1698  struct ast_party_caller caller = ALICE_CALLERID;
1699  struct ast_cdr expected = {
1700  .clid = "\"Alice\" <100>",
1701  .src = "100",
1702  .dst = "100",
1703  .dcontext = "default",
1704  .channel = CHANNEL_TECH_NAME "/Alice",
1705  .dstchannel = CHANNEL_TECH_NAME "/Bob",
1706  .lastapp = "Dial",
1707  .lastdata = CHANNEL_TECH_NAME "/Bob",
1708  .amaflags = AST_AMA_DOCUMENTATION,
1709  .billsec = 1,
1710  .disposition = AST_CDR_ANSWERED,
1711  .accountcode = "100",
1712  .peeraccount = "200",
1713  };
1714 
1715  switch (cmd) {
1716  case TEST_INIT:
1717  info->name = __func__;
1718  info->category = TEST_CATEGORY;
1719  info->summary = "Test dialing, answering, and going into a 2-party bridge";
1720  info->description =
1721  "The most 'basic' of scenarios";
1722  return AST_TEST_NOT_RUN;
1723  case TEST_EXECUTE:
1724  break;
1725  }
1726 
1727  SWAP_CONFIG(config, debug_cdr_config);
1728 
1729  CREATE_ALICE_CHANNEL(chan_caller, &caller, &expected);
1730 
1731  EMULATE_APP_DATA(chan_caller, 1, "Dial", CHANNEL_TECH_NAME "/Bob");
1732 
1733  chan_callee = ast_channel_alloc(0, AST_STATE_DOWN, NULL, NULL, "200", NULL, NULL, NULL, chan_caller, 0, CHANNEL_TECH_NAME "/Bob");
1734  SET_FORMATS(chan_callee);
1735  ast_channel_unlock(chan_callee);
1737  EMULATE_APP_DATA(chan_callee, 0, "AppDial", "(Outgoing Line)");
1738 
1739  ast_channel_publish_dial(chan_caller, chan_callee, "Bob", NULL);
1741  ast_channel_publish_dial(chan_caller, chan_callee, NULL, "ANSWER");
1742 
1743  ast_channel_state_set(chan_caller, AST_STATE_UP);
1744  ast_channel_state_set(chan_callee, AST_STATE_UP);
1745 
1746  bridge = ast_bridge_basic_new();
1747  ast_test_validate(test, bridge != NULL);
1748  do_sleep(&to_sleep);
1749 
1750  ast_test_validate(test, !ast_bridge_impart(bridge, chan_caller, NULL, NULL, AST_BRIDGE_IMPART_CHAN_DEPARTABLE));
1751  ast_test_validate(test, !ast_bridge_impart(bridge, chan_callee, NULL, NULL, AST_BRIDGE_IMPART_CHAN_DEPARTABLE));
1752 
1753  do_sleep(&to_sleep);
1754 
1755  ast_bridge_depart(chan_caller);
1756  ast_bridge_depart(chan_callee);
1757 
1758  HANGUP_CHANNEL(chan_caller, AST_CAUSE_NORMAL);
1759  HANGUP_CHANNEL(chan_callee, AST_CAUSE_NORMAL);
1760 
1761  result = verify_mock_cdr_record(test, &expected, 1);
1762  return result;
1763 }
1764 
1765 AST_TEST_DEFINE(test_cdr_dial_answer_twoparty_bridge_b)
1766 {
1767  RAII_VAR(struct ast_channel *, chan_caller, NULL, safe_channel_release);
1768  RAII_VAR(struct ast_channel *, chan_callee, NULL, safe_channel_release);
1769  RAII_VAR(struct ast_bridge *, bridge, NULL, safe_bridge_destroy);
1770  RAII_VAR(struct ast_cdr_config *, config, ao2_alloc(sizeof(*config), NULL),
1771  ao2_cleanup);
1772  struct timespec to_sleep = {1, 0};
1774 
1775  struct ast_party_caller caller = ALICE_CALLERID;
1776  struct ast_cdr expected = {
1777  .clid = "\"Alice\" <100>",
1778  .src = "100",
1779  .dst = "100",
1780  .dcontext = "default",
1781  .channel = CHANNEL_TECH_NAME "/Alice",
1782  .dstchannel = CHANNEL_TECH_NAME "/Bob",
1783  .lastapp = "Dial",
1784  .lastdata = CHANNEL_TECH_NAME "/Bob",
1785  .amaflags = AST_AMA_DOCUMENTATION,
1786  .billsec = 1,
1787  .disposition = AST_CDR_ANSWERED,
1788  .accountcode = "100",
1789  .peeraccount = "200",
1790  };
1791 
1792  switch (cmd) {
1793  case TEST_INIT:
1794  info->name = __func__;
1795  info->category = TEST_CATEGORY;
1796  info->summary = "Test dialing, answering, and going into a 2-party bridge";
1797  info->description =
1798  "The most 'basic' of scenarios";
1799  return AST_TEST_NOT_RUN;
1800  case TEST_EXECUTE:
1801  break;
1802  }
1803 
1804  SWAP_CONFIG(config, debug_cdr_config);
1805 
1806  CREATE_ALICE_CHANNEL(chan_caller, &caller, &expected);
1807 
1808  EMULATE_APP_DATA(chan_caller, 1, "Dial", CHANNEL_TECH_NAME "/Bob");
1809 
1810  chan_callee = ast_channel_alloc(0, AST_STATE_DOWN, NULL, NULL, "200", NULL, NULL, NULL, chan_caller, 0, CHANNEL_TECH_NAME "/Bob");
1811  SET_FORMATS(chan_callee);
1812  ast_channel_unlock(chan_callee);
1814  EMULATE_APP_DATA(chan_callee, 0, "AppDial", "(Outgoing Line)");
1815 
1816  ast_channel_publish_dial(chan_caller, chan_callee, "Bob", NULL);
1818  ast_channel_publish_dial(chan_caller, chan_callee, NULL, "ANSWER");
1819 
1820  ast_channel_state_set(chan_caller, AST_STATE_UP);
1821  ast_channel_state_set(chan_callee, AST_STATE_UP);
1822 
1823  bridge = ast_bridge_basic_new();
1824  ast_test_validate(test, bridge != NULL);
1825  do_sleep(&to_sleep);
1826  ast_test_validate(test, !ast_bridge_impart(bridge, chan_callee, NULL, NULL, AST_BRIDGE_IMPART_CHAN_DEPARTABLE));
1827  do_sleep(&to_sleep);
1828  ast_test_validate(test, !ast_bridge_impart(bridge, chan_caller, NULL, NULL, AST_BRIDGE_IMPART_CHAN_DEPARTABLE));
1829  do_sleep(&to_sleep);
1830  ast_bridge_depart(chan_caller);
1831  ast_bridge_depart(chan_callee);
1832 
1833  HANGUP_CHANNEL(chan_caller, AST_CAUSE_NORMAL);
1834  HANGUP_CHANNEL(chan_callee, AST_CAUSE_NORMAL);
1835 
1836  result = verify_mock_cdr_record(test, &expected, 1);
1837  return result;
1838 }
1839 
1840 AST_TEST_DEFINE(test_cdr_dial_answer_multiparty)
1841 {
1842  RAII_VAR(struct ast_channel *, chan_alice, NULL, safe_channel_release);
1843  RAII_VAR(struct ast_channel *, chan_bob, NULL, safe_channel_release);
1844  RAII_VAR(struct ast_channel *, chan_charlie, NULL, safe_channel_release);
1845  RAII_VAR(struct ast_channel *, chan_david, NULL, safe_channel_release);
1846  RAII_VAR(struct ast_bridge *, bridge, NULL, safe_bridge_destroy);
1847  RAII_VAR(struct ast_cdr_config *, config, ao2_alloc(sizeof(*config), NULL),
1848  ao2_cleanup);
1849  struct timespec to_sleep = {1, 0};
1851 
1852  struct ast_party_caller alice_caller = ALICE_CALLERID;
1853  struct ast_party_caller charlie_caller = CHARLIE_CALLERID;
1854  struct ast_cdr charlie_expected_two = {
1855  .clid = "\"Charlie\" <300>",
1856  .src = "300",
1857  .dst = "300",
1858  .dcontext = "default",
1859  .channel = CHANNEL_TECH_NAME "/Charlie",
1860  .dstchannel = CHANNEL_TECH_NAME "/Bob",
1861  .lastapp = "Dial",
1862  .lastdata = CHANNEL_TECH_NAME "/David",
1863  .amaflags = AST_AMA_DOCUMENTATION,
1864  .billsec = 1,
1865  .disposition = AST_CDR_ANSWERED,
1866  .accountcode = "300",
1867  .peeraccount = "200",
1868  };
1869  struct ast_cdr charlie_expected_one = {
1870  .clid = "\"Charlie\" <300>",
1871  .src = "300",
1872  .dst = "300",
1873  .dcontext = "default",
1874  .channel = CHANNEL_TECH_NAME "/Charlie",
1875  .dstchannel = CHANNEL_TECH_NAME "/David",
1876  .lastapp = "Dial",
1877  .lastdata = CHANNEL_TECH_NAME "/David",
1878  .amaflags = AST_AMA_DOCUMENTATION,
1879  .billsec = 1,
1880  .disposition = AST_CDR_ANSWERED,
1881  .accountcode = "300",
1882  .peeraccount = "400",
1883  .next = &charlie_expected_two,
1884  };
1885  struct ast_cdr bob_expected_one = {
1886  .clid = "\"Bob\" <200>",
1887  .src = "200",
1888  .dst = "200",
1889  .dcontext = "default",
1890  .channel = CHANNEL_TECH_NAME "/Bob",
1891  .dstchannel = CHANNEL_TECH_NAME "/David",
1892  .lastapp = "AppDial",
1893  .lastdata = "(Outgoing Line)",
1894  .amaflags = AST_AMA_DOCUMENTATION,
1895  .billsec = 1,
1896  .disposition = AST_CDR_ANSWERED,
1897  .accountcode = "200",
1898  .peeraccount = "400",
1899  .next = &charlie_expected_one,
1900  };
1901  struct ast_cdr alice_expected_three = {
1902  .clid = "\"Alice\" <100>",
1903  .src = "100",
1904  .dst = "100",
1905  .dcontext = "default",
1906  .channel = CHANNEL_TECH_NAME "/Alice",
1907  .dstchannel = CHANNEL_TECH_NAME "/David",
1908  .lastapp = "Dial",
1909  .lastdata = CHANNEL_TECH_NAME "/Bob",
1910  .amaflags = AST_AMA_DOCUMENTATION,
1911  .billsec = 1,
1912  .disposition = AST_CDR_ANSWERED,
1913  .accountcode = "100",
1914  .peeraccount = "400",
1915  .next = &bob_expected_one,
1916  };
1917  struct ast_cdr alice_expected_two = {
1918  .clid = "\"Alice\" <100>",
1919  .src = "100",
1920  .dst = "100",
1921  .dcontext = "default",
1922  .channel = CHANNEL_TECH_NAME "/Alice",
1923  .dstchannel = CHANNEL_TECH_NAME "/Charlie",
1924  .lastapp = "Dial",
1925  .lastdata = CHANNEL_TECH_NAME "/Bob",
1926  .amaflags = AST_AMA_DOCUMENTATION,
1927  .billsec = 1,
1928  .disposition = AST_CDR_ANSWERED,
1929  .accountcode = "100",
1930  .peeraccount = "300",
1931  .next = &alice_expected_three,
1932  };
1933  struct ast_cdr alice_expected_one = {
1934  .clid = "\"Alice\" <100>",
1935  .src = "100",
1936  .dst = "100",
1937  .dcontext = "default",
1938  .channel = CHANNEL_TECH_NAME "/Alice",
1939  .dstchannel = CHANNEL_TECH_NAME "/Bob",
1940  .lastapp = "Dial",
1941  .lastdata = CHANNEL_TECH_NAME "/Bob",
1942  .amaflags = AST_AMA_DOCUMENTATION,
1943  .billsec = 1,
1944  .disposition = AST_CDR_ANSWERED,
1945  .accountcode = "100",
1946  .peeraccount = "200",
1947  .next = &alice_expected_two,
1948  };
1949 
1950  switch (cmd) {
1951  case TEST_INIT:
1952  info->name = __func__;
1953  info->category = TEST_CATEGORY;
1954  info->summary = "Test dialing, answering, and going into a multi-party bridge";
1955  info->description =
1956  "A little tricky to get to do, but possible with some redirects.";
1957  return AST_TEST_NOT_RUN;
1958  case TEST_EXECUTE:
1959  break;
1960  }
1961 
1962  SWAP_CONFIG(config, debug_cdr_config);
1963 
1964  CREATE_ALICE_CHANNEL(chan_alice, &alice_caller, &alice_expected_one);
1965  COPY_IDS(chan_alice, &alice_expected_two);
1966  COPY_IDS(chan_alice, &alice_expected_three);
1967 
1968  EMULATE_APP_DATA(chan_alice, 1, "Dial", CHANNEL_TECH_NAME "/Bob");
1969 
1970  chan_bob = ast_channel_alloc(0, AST_STATE_DOWN, "200", "Bob", "200", "200", "default", NULL, NULL, 0, CHANNEL_TECH_NAME "/Bob");
1971  SET_FORMATS(chan_bob);
1972  ast_channel_unlock(chan_bob);
1974  EMULATE_APP_DATA(chan_bob, 0, "AppDial", "(Outgoing Line)");
1975  ast_copy_string(bob_expected_one.uniqueid, ast_channel_uniqueid(chan_bob), sizeof(bob_expected_one.uniqueid));
1976  ast_copy_string(bob_expected_one.linkedid, ast_channel_linkedid(chan_alice), sizeof(bob_expected_one.linkedid));
1977 
1978  CREATE_CHARLIE_CHANNEL(chan_charlie, &charlie_caller, &charlie_expected_one);
1979  EMULATE_APP_DATA(chan_charlie, 1, "Dial", CHANNEL_TECH_NAME "/David");
1980  ast_copy_string(charlie_expected_one.uniqueid, ast_channel_uniqueid(chan_charlie), sizeof(charlie_expected_one.uniqueid));
1981  ast_copy_string(charlie_expected_one.linkedid, ast_channel_linkedid(chan_alice), sizeof(charlie_expected_one.linkedid));
1982  ast_copy_string(charlie_expected_two.uniqueid, ast_channel_uniqueid(chan_charlie), sizeof(charlie_expected_two.uniqueid));
1983  ast_copy_string(charlie_expected_two.linkedid, ast_channel_linkedid(chan_alice), sizeof(charlie_expected_two.linkedid));
1984 
1985  chan_david = ast_channel_alloc(0, AST_STATE_DOWN, "400", "David", "400", "400", "default", NULL, NULL, 0, CHANNEL_TECH_NAME "/David");
1986  SET_FORMATS(chan_david);
1987  ast_channel_unlock(chan_david);
1989  EMULATE_APP_DATA(chan_david, 0, "AppDial", "(Outgoing Line)");
1990 
1991  ast_channel_publish_dial(chan_alice, chan_bob, "Bob", NULL);
1993  ast_channel_publish_dial(chan_charlie, chan_david, "David", NULL);
1995  ast_channel_publish_dial(chan_alice, chan_bob, NULL, "ANSWER");
1996  ast_channel_publish_dial(chan_charlie, chan_david, NULL, "ANSWER");
1997 
1998  ast_channel_state_set(chan_alice, AST_STATE_UP);
2000  ast_channel_state_set(chan_charlie, AST_STATE_UP);
2001  ast_channel_state_set(chan_david, AST_STATE_UP);
2002 
2003  bridge = ast_bridge_basic_new();
2004  ast_test_validate(test, bridge != NULL);
2005 
2006  do_sleep(&to_sleep);
2007  ast_test_validate(test, !ast_bridge_impart(bridge, chan_charlie, NULL, NULL, AST_BRIDGE_IMPART_CHAN_DEPARTABLE));
2008  do_sleep(&to_sleep);
2009  ast_test_validate(test, !ast_bridge_impart(bridge, chan_david, NULL, NULL, AST_BRIDGE_IMPART_CHAN_DEPARTABLE));
2010  do_sleep(&to_sleep);
2011  ast_test_validate(test, !ast_bridge_impart(bridge, chan_bob, NULL, NULL, AST_BRIDGE_IMPART_CHAN_DEPARTABLE));
2012  do_sleep(&to_sleep);
2013  ast_test_validate(test, !ast_bridge_impart(bridge, chan_alice, NULL, NULL, AST_BRIDGE_IMPART_CHAN_DEPARTABLE));
2014  do_sleep(&to_sleep);
2015  ast_test_validate(test, !ast_bridge_depart(chan_alice));
2016  ast_test_validate(test, !ast_bridge_depart(chan_bob));
2017  ast_test_validate(test, !ast_bridge_depart(chan_charlie));
2018  ast_test_validate(test, !ast_bridge_depart(chan_david));
2019 
2020  HANGUP_CHANNEL(chan_alice, AST_CAUSE_NORMAL);
2021  HANGUP_CHANNEL(chan_bob, AST_CAUSE_NORMAL);
2022  HANGUP_CHANNEL(chan_charlie, AST_CAUSE_NORMAL);
2023  HANGUP_CHANNEL(chan_david, AST_CAUSE_NORMAL);
2024 
2025  result = verify_mock_cdr_record(test, &alice_expected_one, 6);
2026 
2027  return result;
2028 }
2029 
2030 AST_TEST_DEFINE(test_cdr_park)
2031 {
2032  RAII_VAR(struct ast_channel *, chan_alice, NULL, safe_channel_release);
2033  RAII_VAR(struct ast_channel *, chan_bob, NULL, safe_channel_release);
2034  RAII_VAR(struct ast_bridge *, bridge, NULL, safe_bridge_destroy);
2035  RAII_VAR(struct ast_cdr_config *, config, ao2_alloc(sizeof(*config), NULL),
2036  ao2_cleanup);
2037  struct timespec to_sleep = {1, 0};
2038 
2039  struct ast_party_caller bob_caller = BOB_CALLERID;
2040  struct ast_party_caller alice_caller = ALICE_CALLERID;
2041  struct ast_cdr bob_expected = {
2042  .clid = "\"Bob\" <200>",
2043  .src = "200",
2044  .dst = "200",
2045  .dcontext = "default",
2046  .channel = CHANNEL_TECH_NAME "/Bob",
2047  .lastapp = "Park",
2048  .lastdata = "701",
2049  .billsec = 1,
2050  .amaflags = AST_AMA_DOCUMENTATION,
2051  .disposition = AST_CDR_ANSWERED,
2052  .accountcode = "200",
2053  };
2054  struct ast_cdr alice_expected = {
2055  .clid = "\"Alice\" <100>",
2056  .src = "100",
2057  .dst = "100",
2058  .dcontext = "default",
2059  .channel = CHANNEL_TECH_NAME "/Alice",
2060  .lastapp = "Park",
2061  .lastdata = "700",
2062  .billsec = 1,
2063  .amaflags = AST_AMA_DOCUMENTATION,
2064  .disposition = AST_CDR_ANSWERED,
2065  .accountcode = "100",
2066  .next = &bob_expected,
2067  };
2069 
2070  switch (cmd) {
2071  case TEST_INIT:
2072  info->name = __func__;
2073  info->category = TEST_CATEGORY;
2074  info->summary = "Test cdrs for a single party entering Park";
2075  info->description =
2076  "Test the properties of a CDR for calls that are\n"
2077  "answered, enters Park, and leaves it.";
2078  return AST_TEST_NOT_RUN;
2079  case TEST_EXECUTE:
2080  break;
2081  }
2082  SWAP_CONFIG(config, debug_cdr_config);
2083  CREATE_ALICE_CHANNEL(chan_alice, &alice_caller, &alice_expected);
2084  CREATE_BOB_CHANNEL(chan_bob, &bob_caller, &bob_expected);
2085 
2086  ast_channel_lock(chan_alice);
2087  EMULATE_APP_DATA(chan_alice, 1, "Park", "700");
2088  ast_setstate(chan_alice, AST_STATE_UP);
2089  ast_channel_unlock(chan_alice);
2090 
2091  ast_channel_lock(chan_bob);
2092  EMULATE_APP_DATA(chan_bob, 1, "Park", "701");
2093  ast_setstate(chan_bob, AST_STATE_UP);
2094  ast_channel_unlock(chan_bob);
2095 
2099  "test_cdr", "test_cdr_park", NULL);
2100  ast_test_validate(test, bridge != NULL);
2101 
2102  do_sleep(&to_sleep);
2103  ast_test_validate(test, !ast_bridge_impart(bridge, chan_alice, NULL, NULL, AST_BRIDGE_IMPART_CHAN_DEPARTABLE));
2104  do_sleep(&to_sleep);
2105  ast_test_validate(test, !ast_bridge_impart(bridge, chan_bob, NULL, NULL, AST_BRIDGE_IMPART_CHAN_DEPARTABLE));
2106  do_sleep(&to_sleep);
2107  ast_bridge_depart(chan_alice);
2108  ast_bridge_depart(chan_bob);
2109 
2110  /* And then it hangs up */
2111  HANGUP_CHANNEL(chan_alice, AST_CAUSE_NORMAL);
2112  HANGUP_CHANNEL(chan_bob, AST_CAUSE_NORMAL);
2113 
2114  result = verify_mock_cdr_record(test, &alice_expected, 2);
2115 
2116  return result;
2117 }
2118 
2119 
2120 AST_TEST_DEFINE(test_cdr_fields)
2121 {
2122  RAII_VAR(struct ast_channel *, chan, NULL, safe_channel_release);
2123  RAII_VAR(struct ast_cdr_config *, config, ao2_alloc(sizeof(*config), NULL),
2124  ao2_cleanup);
2125  char varbuffer[128];
2126  int int_buffer;
2127  double db_buffer;
2128  struct timespec to_sleep = {2, 0};
2129  struct ast_flags fork_options = { 0, };
2130 
2131  struct ast_party_caller caller = ALICE_CALLERID;
2132  struct ast_cdr original = {
2133  .clid = "\"Alice\" <100>",
2134  .src = "100",
2135  .dst = "100",
2136  .dcontext = "default",
2137  .channel = CHANNEL_TECH_NAME "/Alice",
2138  .lastapp = "Wait",
2139  .lastdata = "10",
2140  .billsec = 0,
2141  .amaflags = AST_AMA_OMIT,
2142  .disposition = AST_CDR_FAILED,
2143  .accountcode = "XXX",
2144  .userfield = "yackity",
2145  };
2146  struct ast_cdr fork_expected_one = {
2147  .clid = "\"Alice\" <100>",
2148  .src = "100",
2149  .dst = "100",
2150  .dcontext = "default",
2151  .channel = CHANNEL_TECH_NAME "/Alice",
2152  .lastapp = "Wait",
2153  .lastdata = "10",
2154  .billsec = 0,
2155  .amaflags = AST_AMA_OMIT,
2156  .disposition = AST_CDR_FAILED,
2157  .accountcode = "XXX",
2158  .userfield = "yackity",
2159  };
2160  struct ast_cdr fork_expected_two = {
2161  .clid = "\"Alice\" <100>",
2162  .src = "100",
2163  .dst = "100",
2164  .dcontext = "default",
2165  .channel = CHANNEL_TECH_NAME "/Alice",
2166  .lastapp = "Answer",
2167  .billsec = 0,
2168  .amaflags = AST_AMA_OMIT,
2169  .disposition = AST_CDR_ANSWERED,
2170  .accountcode = "ZZZ",
2171  .userfield = "schmackity",
2172  };
2174 
2175  struct ast_cdr *expected = &original;
2176  original.next = &fork_expected_one;
2177  fork_expected_one.next = &fork_expected_two;
2178 
2179  switch (cmd) {
2180  case TEST_INIT:
2181  info->name = __func__;
2182  info->category = TEST_CATEGORY;
2183  info->summary = "Test field access CDRs";
2184  info->description =
2185  "This tests setting/retrieving data on CDR records.";
2186  return AST_TEST_NOT_RUN;
2187  case TEST_EXECUTE:
2188  break;
2189  }
2190 
2191  SWAP_CONFIG(config, unanswered_cdr_config);
2192 
2193  CREATE_ALICE_CHANNEL(chan, &caller, &original);
2194  ast_copy_string(fork_expected_one.uniqueid, ast_channel_uniqueid(chan), sizeof(fork_expected_one.uniqueid));
2195  ast_copy_string(fork_expected_one.linkedid, ast_channel_linkedid(chan), sizeof(fork_expected_one.linkedid));
2196  ast_copy_string(fork_expected_two.uniqueid, ast_channel_uniqueid(chan), sizeof(fork_expected_two.uniqueid));
2197  ast_copy_string(fork_expected_two.linkedid, ast_channel_linkedid(chan), sizeof(fork_expected_two.linkedid));
2198 
2199  /* Channel enters Wait app */
2200  ast_channel_lock(chan);
2201  ast_channel_appl_set(chan, "Wait");
2202  ast_channel_data_set(chan, "10");
2203  ast_channel_priority_set(chan, 1);
2205 
2206  /* Set properties on the channel that propagate to the CDR */
2208  ast_channel_accountcode_set(chan, "XXX");
2209  ast_channel_unlock(chan);
2210 
2211  /* Wait one second so we get a duration. */
2212  do_sleep(&to_sleep);
2213 
2214  ast_cdr_setuserfield(ast_channel_name(chan), "foobar");
2215  ast_test_validate(test, ast_cdr_setvar(ast_channel_name(chan), "test_variable", "record_1") == 0);
2216 
2217  /* Verify that we can't set read-only fields or other fields directly */
2218  ast_test_validate(test, ast_cdr_setvar(ast_channel_name(chan), "clid", "junk") != 0);
2219  ast_test_validate(test, ast_cdr_setvar(ast_channel_name(chan), "src", "junk") != 0);
2220  ast_test_validate(test, ast_cdr_setvar(ast_channel_name(chan), "dst", "junk") != 0);
2221  ast_test_validate(test, ast_cdr_setvar(ast_channel_name(chan), "dcontext", "junk") != 0);
2222  ast_test_validate(test, ast_cdr_setvar(ast_channel_name(chan), "channel", "junk") != 0);
2223  ast_test_validate(test, ast_cdr_setvar(ast_channel_name(chan), "dstchannel", "junk") != 0);
2224  ast_test_validate(test, ast_cdr_setvar(ast_channel_name(chan), "lastapp", "junk") != 0);
2225  ast_test_validate(test, ast_cdr_setvar(ast_channel_name(chan), "lastdata", "junk") != 0);
2226  ast_test_validate(test, ast_cdr_setvar(ast_channel_name(chan), "start", "junk") != 0);
2227  ast_test_validate(test, ast_cdr_setvar(ast_channel_name(chan), "answer", "junk") != 0);
2228  ast_test_validate(test, ast_cdr_setvar(ast_channel_name(chan), "end", "junk") != 0);
2229  ast_test_validate(test, ast_cdr_setvar(ast_channel_name(chan), "duration", "junk") != 0);
2230  ast_test_validate(test, ast_cdr_setvar(ast_channel_name(chan), "billsec", "junk") != 0);
2231  ast_test_validate(test, ast_cdr_setvar(ast_channel_name(chan), "disposition", "junk") != 0);
2232  ast_test_validate(test, ast_cdr_setvar(ast_channel_name(chan), "amaflags", "junk") != 0);
2233  ast_test_validate(test, ast_cdr_setvar(ast_channel_name(chan), "accountcode", "junk") != 0);
2234  ast_test_validate(test, ast_cdr_setvar(ast_channel_name(chan), "uniqueid", "junk") != 0);
2235  ast_test_validate(test, ast_cdr_setvar(ast_channel_name(chan), "linkedid", "junk") != 0);
2236  ast_test_validate(test, ast_cdr_setvar(ast_channel_name(chan), "userfield", "junk") != 0);
2237  ast_test_validate(test, ast_cdr_setvar(ast_channel_name(chan), "sequence", "junk") != 0);
2238 
2239  /* Verify the values */
2240  ast_test_validate(test, ast_cdr_getvar(ast_channel_name(chan), "userfield", varbuffer, sizeof(varbuffer)) == 0);
2241  ast_test_validate(test, strcmp(varbuffer, "foobar") == 0);
2242  ast_test_validate(test, ast_cdr_getvar(ast_channel_name(chan), "test_variable", varbuffer, sizeof(varbuffer)) == 0);
2243  ast_test_validate(test, strcmp(varbuffer, "record_1") == 0);
2244  ast_test_validate(test, ast_cdr_getvar(ast_channel_name(chan), "amaflags", varbuffer, sizeof(varbuffer)) == 0);
2245  sscanf(varbuffer, "%d", &int_buffer);
2246  ast_test_validate(test, int_buffer == AST_AMA_OMIT);
2247  ast_test_validate(test, ast_cdr_getvar(ast_channel_name(chan), "accountcode", varbuffer, sizeof(varbuffer)) == 0);
2248  ast_test_validate(test, strcmp(varbuffer, "XXX") == 0);
2249  ast_test_validate(test, ast_cdr_getvar(ast_channel_name(chan), "clid", varbuffer, sizeof(varbuffer)) == 0);
2250  ast_test_validate(test, strcmp(varbuffer, "\"Alice\" <100>") == 0);
2251  ast_test_validate(test, ast_cdr_getvar(ast_channel_name(chan), "src", varbuffer, sizeof(varbuffer)) == 0);
2252  ast_test_validate(test, strcmp(varbuffer, "100") == 0);
2253  ast_test_validate(test, ast_cdr_getvar(ast_channel_name(chan), "dst", varbuffer, sizeof(varbuffer)) == 0);
2254  ast_test_validate(test, strcmp(varbuffer, "100") == 0);
2255  ast_test_validate(test, ast_cdr_getvar(ast_channel_name(chan), "dcontext", varbuffer, sizeof(varbuffer)) == 0);
2256  ast_test_validate(test, strcmp(varbuffer, "default") == 0);
2257  ast_test_validate(test, ast_cdr_getvar(ast_channel_name(chan), "channel", varbuffer, sizeof(varbuffer)) == 0);
2258  ast_test_validate(test, strcmp(varbuffer, CHANNEL_TECH_NAME "/Alice") == 0);
2259  ast_test_validate(test, ast_cdr_getvar(ast_channel_name(chan), "dstchannel", varbuffer, sizeof(varbuffer)) == 0);
2260  ast_test_validate(test, strcmp(varbuffer, "") == 0);
2261  ast_test_validate(test, ast_cdr_getvar(ast_channel_name(chan), "lastapp", varbuffer, sizeof(varbuffer)) == 0);
2262  ast_test_validate(test, strcmp(varbuffer, "Wait") == 0);
2263  ast_test_validate(test, ast_cdr_getvar(ast_channel_name(chan), "lastdata", varbuffer, sizeof(varbuffer)) == 0);
2264  ast_test_validate(test, strcmp(varbuffer, "10") == 0);
2265  ast_test_validate(test, ast_cdr_getvar(ast_channel_name(chan), "start", varbuffer, sizeof(varbuffer)) == 0);
2266  sscanf(varbuffer, "%lf", &db_buffer);
2267  ast_test_validate(test, fabs(db_buffer) > 0);
2268  ast_test_validate(test, ast_cdr_getvar(ast_channel_name(chan), "answer", varbuffer, sizeof(varbuffer)) == 0);
2269  sscanf(varbuffer, "%lf", &db_buffer);
2270  ast_test_validate(test, fabs(db_buffer) < EPSILON);
2271  ast_test_validate(test, ast_cdr_getvar(ast_channel_name(chan), "end", varbuffer, sizeof(varbuffer)) == 0);
2272  sscanf(varbuffer, "%lf", &db_buffer);
2273  ast_test_validate(test, fabs(db_buffer) < EPSILON);
2274  ast_test_validate(test, ast_cdr_getvar(ast_channel_name(chan), "duration", varbuffer, sizeof(varbuffer)) == 0);
2275  sscanf(varbuffer, "%lf", &db_buffer);
2276  ast_test_validate(test, fabs(db_buffer) > 0);
2277  ast_test_validate(test, ast_cdr_getvar(ast_channel_name(chan), "billsec", varbuffer, sizeof(varbuffer)) == 0);
2278  sscanf(varbuffer, "%lf", &db_buffer);
2279  ast_test_validate(test, fabs(db_buffer) < EPSILON);
2280  ast_test_validate(test, ast_cdr_getvar(ast_channel_name(chan), "disposition", varbuffer, sizeof(varbuffer)) == 0);
2281  sscanf(varbuffer, "%d", &int_buffer);
2282  ast_test_validate(test, int_buffer == AST_CDR_NULL);
2283  ast_test_validate(test, ast_cdr_getvar(ast_channel_name(chan), "uniqueid", varbuffer, sizeof(varbuffer)) == 0);
2284  ast_test_validate(test, strcmp(varbuffer, ast_channel_uniqueid(chan)) == 0);
2285  ast_test_validate(test, ast_cdr_getvar(ast_channel_name(chan), "linkedid", varbuffer, sizeof(varbuffer)) == 0);
2286  ast_test_validate(test, strcmp(varbuffer, ast_channel_linkedid(chan)) == 0);
2287  ast_test_validate(test, ast_cdr_getvar(ast_channel_name(chan), "sequence", varbuffer, sizeof(varbuffer)) == 0);
2288 
2289  /* Fork the CDR, and check that we change the properties on both CDRs. */
2290  ast_set_flag(&fork_options, AST_CDR_FLAG_KEEP_VARS);
2291  ast_test_validate(test, ast_cdr_fork(ast_channel_name(chan), &fork_options) == 0);
2292 
2293  /* Change some properties */
2294  ast_cdr_setuserfield(ast_channel_name(chan), "yackity");
2295  ast_test_validate(test, ast_cdr_setvar(ast_channel_name(chan), "test_variable", "record_1b") == 0);
2296 
2297  /* Fork the CDR again, finalizing all current CDRs */
2299  ast_test_validate(test, ast_cdr_fork(ast_channel_name(chan), &fork_options) == 0);
2300 
2301  /* Channel enters Answer app */
2302  ast_channel_lock(chan);
2303  ast_channel_appl_set(chan, "Answer");
2304  ast_channel_data_set(chan, "");
2305  ast_channel_priority_set(chan, 1);
2307  ast_setstate(chan, AST_STATE_UP);
2308 
2309  /* Set properties on the last record */
2310  ast_channel_accountcode_set(chan, "ZZZ");
2311  ast_channel_unlock(chan);
2312  ast_cdr_setuserfield(ast_channel_name(chan), "schmackity");
2313  ast_test_validate(test, ast_cdr_setvar(ast_channel_name(chan), "test_variable", "record_2") == 0);
2314 
2315  /* Hang up and verify */
2317  ast_hangup(chan);
2318  chan = NULL;
2319  result = verify_mock_cdr_record(test, expected, 3);
2320 
2321  return result;
2322 }
2323 
2324 AST_TEST_DEFINE(test_cdr_no_reset_cdr)
2325 {
2326  RAII_VAR(struct ast_channel *, chan, NULL, safe_channel_release);
2327  RAII_VAR(struct ast_cdr_config *, config, ao2_alloc(sizeof(*config), NULL),
2328  ao2_cleanup);
2329  struct ast_flags fork_options = { 0, };
2330  struct timespec to_sleep = {1, 0};
2331 
2332  struct ast_party_caller caller = ALICE_CALLERID;
2333  struct ast_cdr expected = {
2334  .clid = "\"Alice\" <100>",
2335  .src = "100",
2336  .dst = "100",
2337  .dcontext = "default",
2338  .channel = CHANNEL_TECH_NAME "/Alice",
2339  .billsec = 0,
2340  .amaflags = AST_AMA_DOCUMENTATION,
2341  .disposition = AST_CDR_FAILED,
2342  .accountcode = "100",
2343  };
2345 
2346  switch (cmd) {
2347  case TEST_INIT:
2348  info->name = __func__;
2349  info->category = TEST_CATEGORY;
2350  info->summary = "Test field access CDRs";
2351  info->description =
2352  "This tests setting/retrieving data on CDR records.";
2353  return AST_TEST_NOT_RUN;
2354  case TEST_EXECUTE:
2355  break;
2356  }
2357 
2358  SWAP_CONFIG(config, unanswered_cdr_config);
2359 
2360  CREATE_ALICE_CHANNEL(chan, &caller, &expected);
2361 
2362  do_sleep(&to_sleep);
2363 
2364  /* Disable the CDR */
2365  ast_test_validate(test, ast_cdr_set_property(ast_channel_name(chan), AST_CDR_FLAG_DISABLE) == 0);
2366 
2367  /* Fork the CDR. This should be enabled */
2368  ast_set_flag(&fork_options, AST_CDR_FLAG_FINALIZE);
2369  ast_test_validate(test, ast_cdr_fork(ast_channel_name(chan), &fork_options) == 0);
2370 
2371  /* Disable and enable the forked CDR */
2372  ast_test_validate(test, ast_cdr_set_property(ast_channel_name(chan), AST_CDR_FLAG_DISABLE) == 0);
2373  ast_test_validate(test, ast_cdr_clear_property(ast_channel_name(chan), AST_CDR_FLAG_DISABLE) == 0);
2374 
2375  /* Fork and finalize again. This CDR should be propagated */
2376  ast_test_validate(test, ast_cdr_fork(ast_channel_name(chan), &fork_options) == 0);
2377 
2378  /* Disable all future CDRs */
2379  ast_test_validate(test, ast_cdr_set_property(ast_channel_name(chan), AST_CDR_FLAG_DISABLE_ALL) == 0);
2380 
2381  /* Fork a few more */
2382  ast_test_validate(test, ast_cdr_fork(ast_channel_name(chan), &fork_options) == 0);
2383  ast_test_validate(test, ast_cdr_fork(ast_channel_name(chan), &fork_options) == 0);
2384  ast_test_validate(test, ast_cdr_fork(ast_channel_name(chan), &fork_options) == 0);
2385 
2387  ast_hangup(chan);
2388  chan = NULL;
2389  result = verify_mock_cdr_record(test, &expected, 1);
2390 
2391  return result;
2392 }
2393 
2394 AST_TEST_DEFINE(test_cdr_fork_cdr)
2395 {
2396  RAII_VAR(struct ast_channel *, chan, NULL, safe_channel_release);
2397  RAII_VAR(struct ast_cdr_config *, config, ao2_alloc(sizeof(*config), NULL),
2398  ao2_cleanup);
2399  char varbuffer[128];
2400  char fork_varbuffer[128];
2401  char answer_time[128];
2402  char fork_answer_time[128];
2403  char start_time[128];
2404  char fork_start_time[128];
2405  struct ast_flags fork_options = { 0, };
2406  struct timespec to_sleep = {1, 10000};
2407 
2408  struct ast_party_caller caller = ALICE_CALLERID;
2409  struct ast_cdr original = {
2410  .clid = "\"Alice\" <100>",
2411  .src = "100",
2412  .dst = "100",
2413  .dcontext = "default",
2414  .channel = CHANNEL_TECH_NAME "/Alice",
2415  .amaflags = AST_AMA_DOCUMENTATION,
2416  .disposition = AST_CDR_ANSWERED,
2417  .accountcode = "100",
2418  };
2419  struct ast_cdr fork_expected_one = {
2420  .clid = "\"Alice\" <100>",
2421  .src = "100",
2422  .dst = "100",
2423  .dcontext = "default",
2424  .channel = CHANNEL_TECH_NAME "/Alice",
2425  .amaflags = AST_AMA_DOCUMENTATION,
2426  .disposition = AST_CDR_ANSWERED,
2427  .accountcode = "100",
2428  };
2429  struct ast_cdr fork_expected_two = {
2430  .clid = "\"Alice\" <100>",
2431  .src = "100",
2432  .dst = "100",
2433  .dcontext = "default",
2434  .channel = CHANNEL_TECH_NAME "/Alice",
2435  .amaflags = AST_AMA_DOCUMENTATION,
2436  .disposition = AST_CDR_ANSWERED,
2437  .accountcode = "100",
2438  };
2440  struct ast_cdr *expected = &original;
2441  original.next = &fork_expected_one;
2442  fork_expected_one.next = &fork_expected_two;
2443 
2444  switch (cmd) {
2445  case TEST_INIT:
2446  info->name = __func__;
2447  info->category = TEST_CATEGORY;
2448  info->summary = "Test field access CDRs";
2449  info->description =
2450  "This tests setting/retrieving data on CDR records.";
2451  return AST_TEST_NOT_RUN;
2452  case TEST_EXECUTE:
2453  break;
2454  }
2455 
2456  SWAP_CONFIG(config, debug_cdr_config);
2457 
2458  CREATE_ALICE_CHANNEL(chan, &caller, &original);
2459  ast_copy_string(fork_expected_one.uniqueid, ast_channel_uniqueid(chan), sizeof(fork_expected_one.uniqueid));
2460  ast_copy_string(fork_expected_one.linkedid, ast_channel_linkedid(chan), sizeof(fork_expected_one.linkedid));
2461  ast_copy_string(fork_expected_two.uniqueid, ast_channel_uniqueid(chan), sizeof(fork_expected_two.uniqueid));
2462  ast_copy_string(fork_expected_two.linkedid, ast_channel_linkedid(chan), sizeof(fork_expected_two.linkedid));
2463 
2464  do_sleep(&to_sleep);
2465 
2466  /* Test blowing away variables */
2467  ast_test_validate(test, ast_cdr_setvar(ast_channel_name(chan), "test_variable", "record_1") == 0);
2468  ast_test_validate(test, ast_cdr_getvar(ast_channel_name(chan), "test_variable", varbuffer, sizeof(varbuffer)) == 0);
2469  ast_test_validate(test, strcmp(varbuffer, "record_1") == 0);
2470  ast_copy_string(varbuffer, "", sizeof(varbuffer));
2471 
2472  ast_test_validate(test, ast_cdr_fork(ast_channel_name(chan), &fork_options) == 0);
2473  ast_test_validate(test, ast_cdr_getvar(ast_channel_name(chan), "test_variable", fork_varbuffer, sizeof(fork_varbuffer)) == 0);
2474  ast_test_validate(test, strcmp(varbuffer, "record_1") != 0);
2475 
2476  /* Test finalizing previous CDRs */
2477  ast_set_flag(&fork_options, AST_CDR_FLAG_FINALIZE);
2478  ast_test_validate(test, ast_cdr_fork(ast_channel_name(chan), &fork_options) == 0);
2479 
2480  /* Test keep variables; setting a new answer time */
2481  ast_channel_lock(chan);
2482  ast_setstate(chan, AST_STATE_UP);
2483  ast_channel_unlock(chan);
2484  do_sleep(&to_sleep);
2485  ast_test_validate(test, ast_cdr_setvar(ast_channel_name(chan), "test_variable", "record_2") == 0);
2486  ast_test_validate(test, ast_cdr_getvar(ast_channel_name(chan), "test_variable", varbuffer, sizeof(varbuffer)) == 0);
2487  ast_test_validate(test, strcmp(varbuffer, "record_2") == 0);
2488  ast_test_validate(test, ast_cdr_getvar(ast_channel_name(chan), "answer", answer_time, sizeof(answer_time)) == 0);
2489  ast_test_validate(test, ast_cdr_getvar(ast_channel_name(chan), "start", start_time, sizeof(start_time)) == 0);
2490 
2491  ast_set_flag(&fork_options, AST_CDR_FLAG_FINALIZE);
2492  ast_set_flag(&fork_options, AST_CDR_FLAG_KEEP_VARS);
2493  ast_set_flag(&fork_options, AST_CDR_FLAG_SET_ANSWER);
2494  ast_test_validate(test, ast_cdr_fork(ast_channel_name(chan), &fork_options) == 0);
2495  ast_test_validate(test, ast_cdr_getvar(ast_channel_name(chan), "answer", fork_answer_time, sizeof(fork_answer_time)) == 0);
2496  ast_test_validate(test, ast_cdr_getvar(ast_channel_name(chan), "start", fork_start_time, sizeof(fork_start_time)) == 0);
2497  ast_test_validate(test, ast_cdr_getvar(ast_channel_name(chan), "test_variable", fork_varbuffer, sizeof(fork_varbuffer)) == 0);
2498  ast_test_validate(test, strcmp(fork_varbuffer, varbuffer) == 0);
2499  ast_test_validate(test, strcmp(fork_start_time, start_time) == 0);
2500  ast_test_validate(test, strcmp(fork_answer_time, answer_time) != 0);
2501 
2502  ast_clear_flag(&fork_options, AST_CDR_FLAG_SET_ANSWER);
2503  ast_set_flag(&fork_options, AST_CDR_FLAG_RESET);
2504  ast_test_validate(test, ast_cdr_fork(ast_channel_name(chan), &fork_options) == 0);
2505  ast_test_validate(test, ast_cdr_getvar(ast_channel_name(chan), "answer", fork_answer_time, sizeof(fork_answer_time)) == 0);
2506  ast_test_validate(test, ast_cdr_getvar(ast_channel_name(chan), "start", fork_start_time, sizeof(fork_start_time)) == 0);
2507  ast_test_validate(test, strcmp(fork_start_time, start_time) != 0);
2508  ast_test_validate(test, strcmp(fork_answer_time, answer_time) != 0);
2509 
2511  ast_hangup(chan);
2512  chan = NULL;
2513  result = verify_mock_cdr_record(test, expected, 3);
2514 
2515  return result;
2516 }
2517 
2518 /*!
2519  * \internal
2520  * \brief Callback function called before each test executes
2521  */
2522 static int test_cdr_init_cb(struct ast_test_info *info, struct ast_test *test)
2523 {
2524  /* Back up the real config */
2525  saved_config = ast_cdr_get_config();
2527  return 0;
2528 }
2529 
2530 /*!
2531  * \internal
2532  * \brief Callback function called after each test executes
2533  */
2535 {
2536  /* Restore the real config */
2537  ast_cdr_set_config(saved_config);
2538  ao2_cleanup(saved_config);
2539  saved_config = NULL;
2541 
2542  return 0;
2543 }
2544 
2545 
2546 static int unload_module(void)
2547 {
2548  AST_TEST_UNREGISTER(test_cdr_channel_creation);
2549  AST_TEST_UNREGISTER(test_cdr_unanswered_inbound_call);
2550  AST_TEST_UNREGISTER(test_cdr_unanswered_outbound_call);
2551 
2552  AST_TEST_UNREGISTER(test_cdr_single_party);
2553  AST_TEST_UNREGISTER(test_cdr_single_bridge);
2554  AST_TEST_UNREGISTER(test_cdr_single_bridge_continue);
2555  AST_TEST_UNREGISTER(test_cdr_single_twoparty_bridge_a);
2556  AST_TEST_UNREGISTER(test_cdr_single_twoparty_bridge_b);
2557  AST_TEST_UNREGISTER(test_cdr_single_multiparty_bridge);
2558 
2559  AST_TEST_UNREGISTER(test_cdr_outbound_bridged_call);
2560 
2561  AST_TEST_UNREGISTER(test_cdr_dial_unanswered);
2562  AST_TEST_UNREGISTER(test_cdr_dial_congestion);
2563  AST_TEST_UNREGISTER(test_cdr_dial_busy);
2564  AST_TEST_UNREGISTER(test_cdr_dial_unavailable);
2565  AST_TEST_UNREGISTER(test_cdr_dial_caller_cancel);
2566  AST_TEST_UNREGISTER(test_cdr_dial_parallel_failed);
2567  AST_TEST_UNREGISTER(test_cdr_dial_answer_no_bridge);
2568  AST_TEST_UNREGISTER(test_cdr_dial_answer_twoparty_bridge_a);
2569  AST_TEST_UNREGISTER(test_cdr_dial_answer_twoparty_bridge_b);
2570  AST_TEST_UNREGISTER(test_cdr_dial_answer_multiparty);
2571 
2572  AST_TEST_UNREGISTER(test_cdr_park);
2573 
2574  AST_TEST_UNREGISTER(test_cdr_fields);
2575  AST_TEST_UNREGISTER(test_cdr_no_reset_cdr);
2576  AST_TEST_UNREGISTER(test_cdr_fork_cdr);
2577 
2579  ast_channel_unregister(&test_cdr_chan_tech);
2581 
2582  return 0;
2583 }
2584 
2585 static int load_module(void)
2586 {
2588 
2589  AST_TEST_REGISTER(test_cdr_channel_creation);
2590  AST_TEST_REGISTER(test_cdr_unanswered_inbound_call);
2591  AST_TEST_REGISTER(test_cdr_unanswered_outbound_call);
2592 
2593  AST_TEST_REGISTER(test_cdr_single_party);
2594  AST_TEST_REGISTER(test_cdr_single_bridge);
2595  AST_TEST_REGISTER(test_cdr_single_bridge_continue);
2596  AST_TEST_REGISTER(test_cdr_single_twoparty_bridge_a);
2597  AST_TEST_REGISTER(test_cdr_single_twoparty_bridge_b);
2598  AST_TEST_REGISTER(test_cdr_single_multiparty_bridge);
2599 
2600  AST_TEST_REGISTER(test_cdr_outbound_bridged_call);
2601 
2602  AST_TEST_REGISTER(test_cdr_dial_unanswered);
2603  AST_TEST_REGISTER(test_cdr_dial_congestion);
2604  AST_TEST_REGISTER(test_cdr_dial_busy);
2605  AST_TEST_REGISTER(test_cdr_dial_unavailable);
2606  AST_TEST_REGISTER(test_cdr_dial_caller_cancel);
2607  AST_TEST_REGISTER(test_cdr_dial_parallel_failed);
2608  AST_TEST_REGISTER(test_cdr_dial_answer_no_bridge);
2609  AST_TEST_REGISTER(test_cdr_dial_answer_twoparty_bridge_a);
2610  AST_TEST_REGISTER(test_cdr_dial_answer_twoparty_bridge_b);
2611  AST_TEST_REGISTER(test_cdr_dial_answer_multiparty);
2612 
2613  AST_TEST_REGISTER(test_cdr_park);
2614 
2615  AST_TEST_REGISTER(test_cdr_fields);
2616  AST_TEST_REGISTER(test_cdr_no_reset_cdr);
2617  AST_TEST_REGISTER(test_cdr_fork_cdr);
2618 
2621 
2622  ast_channel_register(&test_cdr_chan_tech);
2624 
2625  return AST_MODULE_LOAD_SUCCESS;
2626 }
2627 
#define EMULATE_APP_DATA(channel, priority, application, data)
Emulate a channel entering into an application.
Definition: test_cdr.c:291
Contains all the initialization information required to store a new test definition.
Definition: test.h:221
static char accountcode[AST_MAX_ACCOUNT_CODE]
Definition: chan_iax2.c:428
void ast_test_debug(struct ast_test *test, const char *fmt,...)
Definition: test.c:113
#define ast_channel_lock(chan)
Definition: channel.h:2945
Main Channel structure associated with a channel.
#define AST_MODULE_INFO_STANDARD(keystr, desc)
Definition: module.h:567
#define AST_LIST_LOCK(head)
Locks a list.
Definition: linkedlists.h:39
int ast_cdr_setvar(const char *channel_name, const char *name, const char *value)
Set a variable on a CDR.
Definition: cdr.c:3178
const char *const type
Definition: channel.h:630
Asterisk main include file. File version handling, generic pbx functions.
static int test_cdr_init_cb(struct ast_test_info *info, struct ast_test *test)
Definition: test_cdr.c:2522
int ast_cdr_unregister(const char *name)
Unregister a CDR handling engine.
Definition: cdr.c:2988
#define AST_LIST_HEAD(name, type)
Defines a structure to be used to hold a list of specified type.
Definition: linkedlists.h:172
static int amaflags
Definition: chan_iax2.c:431
static int test_cdr_cleanup_cb(struct ast_test_info *info, struct ast_test *test)
Definition: test_cdr.c:2534
char * config
Definition: conf2ael.c:66
char dstchannel[AST_MAX_EXTENSION]
Definition: cdr.h:288
static void do_sleep(struct timespec *to_sleep)
Definition: test_cdr.c:387
struct ast_flags settings
Definition: cdr.h:265
int ast_test_register_init(const char *category, ast_test_init_cb_t *cb)
Definition: test.c:160
AST_TEST_DEFINE(test_cdr_channel_creation)
Definition: test_cdr.c:393
Time-related functions and macros.
struct ast_party_name name
Subscriber name.
Definition: channel.h:341
void ast_channel_unregister(const struct ast_channel_tech *tech)
Unregister a channel technology.
Definition: channel.c:570
void ast_channel_publish_dial(struct ast_channel *caller, struct ast_channel *peer, const char *dialstring, const char *dialstatus)
Publish in the ast_channel_topic or ast_channel_topic_all topics a stasis message for the channels in...
void ast_channel_appl_set(struct ast_channel *chan, const char *value)
int ast_cdr_getvar(const char *channel_name, const char *name, char *value, size_t length)
Retrieve a CDR variable from a channel&#39;s current CDR.
Definition: cdr.c:3324
void ast_channel_hangupcause_set(struct ast_channel *chan, int value)
static struct ast_cdr_config congestion_cdr_config
A configuration suitable for CDRs with congestion enabled.
Definition: test_cdr.c:71
#define TEST_CATEGORY
Definition: test_cdr.c:51
#define CREATE_ALICE_CHANNEL(channel_var, caller_id, expected_record)
Create a test_cdr_chan_tech for Alice, and set the expected CDR records&#39; linkedid and uniqueid...
Definition: test_cdr.c:248
Channel Variables.
struct ast_channel * ast_channel_release(struct ast_channel *chan)
Unlink and release reference to a channel.
Definition: channel.c:1584
#define EPSILON
Definition: test_cdr.c:49
long int billsec
Definition: cdr.h:302
#define ast_set_flag(p, flag)
Definition: utils.h:70
struct ast_var_t * last
Definition: chanvars.h:34
void ast_cdr_set_config(struct ast_cdr_config *config)
Set the current CDR configuration.
Definition: cdr.c:2840
struct ast_cdr * next
Definition: cdr.h:325
#define COPY_IDS(channel_var, expected_record)
Copy the linkedid and uniqueid from a channel to an expected CDR.
Definition: test_cdr.c:228
#define AST_LIST_UNLOCK(head)
Attempts to unlock a list.
Definition: linkedlists.h:139
int ast_cdr_fork(const char *channel_name, struct ast_flags *options)
Fork a CDR.
Definition: cdr.c:3637
unsigned int flags
Definition: utils.h:200
#define SET_FORMATS(chan)
Set ulaw format on channel.
Definition: test_cdr.c:234
Test Framework API.
#define AST_TEST_REGISTER(cb)
Definition: test.h:127
char * str
Subscriber name (Malloced)
Definition: channel.h:265
int ast_bridge_destroy(struct ast_bridge *bridge, int cause)
Destroy a bridge.
Definition: bridge.c:970
static int unload_module(void)
Definition: test_cdr.c:2546
struct ast_cdr * cdr
Definition: test_cdr.c:97
#define ast_cond_init(cond, attr)
Definition: lock.h:199
static int load_module(void)
Definition: test_cdr.c:2585
struct timeval ast_tvnow(void)
Returns current timeval. Meant to replace calls to gettimeofday().
Definition: time.h:150
#define SWAP_CONFIG(ao2_config, template)
Macro to swap a configuration out from the CDR engine. This should be used at the beginning of each t...
Definition: test_cdr.c:79
int ast_channel_register(const struct ast_channel_tech *tech)
Register a channel technology (a new channel driver) Called by a channel module to register the kind ...
Definition: channel.c:539
Definition: muted.c:95
#define HANGUP_CHANNEL(channel, cause)
Hang up a test channel safely.
Definition: test_cdr.c:303
static void clear_mock_cdr_backend(void)
Definition: test_cdr.c:169
#define MOCK_CDR_BACKEND
Definition: test_cdr.c:53
#define NULL
Definition: resample.c:96
char * end
Definition: eagi_proxy.c:73
#define ast_cond_signal(cond)
Definition: lock.h:201
static struct timespec to_sleep
A 1 second sleep.
Definition: test_cel.c:85
struct test_cdr_entry::@505 list
const char * ast_channel_linkedid(const struct ast_channel *chan)
Utility functions.
pthread_cond_t ast_cond_t
Definition: lock.h:176
struct varshead varshead
Definition: cdr.h:323
static struct @504 actual_cdr_entries
A linked list of received CDR entries from the engine.
Call Detail Record API.
struct ast_party_id id
Caller party ID.
Definition: channel.h:421
Definition: test_cdr.c:96
#define ALICE_CALLERID
Alice&#39;s Caller ID.
Definition: test_cdr.c:216
int ast_cdr_register(const char *name, const char *desc, ast_cdrbe be)
Register a CDR handling engine.
Definition: cdr.c:2943
int ast_bridge_impart(struct ast_bridge *bridge, struct ast_channel *chan, struct ast_channel *swap, struct ast_bridge_features *features, enum ast_bridge_impart_flags flags) attribute_warn_unused_result
Impart a channel to a bridge (non-blocking)
Definition: bridge.c:1924
#define RAII_VAR(vartype, varname, initval, dtor)
Declare a variable that will call a destructor function when it goes out of scope.
Definition: utils.h:911
#define ast_test_status_update(a, b, c...)
Definition: test.h:129
#define CREATE_CHARLIE_CHANNEL(channel_var, caller_id, expected_record)
Create a test_cdr_chan_tech for Charlie, and set the expected CDR records&#39; linkedid and uniqueid...
Definition: test_cdr.c:270
char linkedid[AST_MAX_UNIQUEID]
Definition: cdr.h:316
Caller Party information.
Definition: channel.h:419
#define CHARLIE_CALLERID
Charlie&#39;s Caller ID.
Definition: test_cdr.c:222
char uniqueid[AST_MAX_UNIQUEID]
Definition: cdr.h:314
static struct ast_cdr_config * saved_config
A placeholder for Asterisk&#39;s &#39;real&#39; CDR configuration.
Definition: test_cdr.c:58
void ast_channel_amaflags_set(struct ast_channel *chan, enum ama_flags value)
A set of macros to manage forward-linked lists.
Definition: cdr.h:226
static enum ast_test_result_state verify_mock_cdr_record(struct ast_test *test, struct ast_cdr *expected, int record)
Definition: test_cdr.c:310
char channel[AST_MAX_EXTENSION]
Definition: cdr.h:286
#define AST_LIST_REMOVE_HEAD(head, field)
Removes and returns the head entry from a list.
Definition: linkedlists.h:832
#define AST_CAUSE_NO_ANSWER
Definition: causes.h:108
struct ast_bridge * ast_bridge_base_new(uint32_t capabilities, unsigned int flags, const char *creator, const char *name, const char *id)
Create a new base class bridge.
Definition: bridge.c:960
static int answer(void *data)
Definition: chan_pjsip.c:682
Structure to describe a channel "technology", ie a channel driver See for examples: ...
Definition: channel.h:629
int ast_test_register_cleanup(const char *category, ast_test_cleanup_cb_t *cb)
Definition: test.c:177
struct ast_var_t * first
Definition: chanvars.h:34
const char * ast_channel_uniqueid(const struct ast_channel *chan)
#define AST_CAUSE_NORMAL
Definition: causes.h:150
int ast_cdr_set_property(const char *channel_name, enum ast_cdr_options option)
Set a property on a CDR for a channel.
Definition: cdr.c:3548
Responsible for call detail data.
Definition: cdr.h:276
Structure that contains information about a bridge.
Definition: bridge.h:357
char name[0]
Definition: chanvars.h:31
#define AST_LIST_INSERT_TAIL(head, elm, field)
Appends a list entry to the tail of a list.
Definition: linkedlists.h:730
static int mock_cdr_backend_cb(struct ast_cdr *cdr)
Definition: test_cdr.c:116
#define AST_TEST_UNREGISTER(cb)
Definition: test.h:128
#define CREATE_BOB_CHANNEL(channel_var, caller_id, expected_record)
Create a test_cdr_chan_tech for Bob, and set the expected CDR records&#39; linkedid and uniqueid...
Definition: test_cdr.c:259
def info(msg)
char * value
Definition: chanvars.h:30
int errno
int ast_bridge_depart(struct ast_channel *chan)
Depart a channel from a bridge.
Definition: bridge.c:1952
static ast_cond_t mock_cdr_cond
The Mock CDR backend condition wait.
Definition: test_cdr.c:88
#define ao2_alloc(data_size, destructor_fn)
Definition: astobj2.h:411
#define AST_LIST_TRAVERSE(head, var, field)
Loops over (traverses) the entries in a list.
Definition: linkedlists.h:490
#define AST_LIST_ENTRY(type)
Declare a forward link structure inside a list entry.
Definition: linkedlists.h:409
#define VERIFY_TIME_VALUE(field, actual)
Verify a time field. This will set the test status result to fail; as such, it assumes that (a) test ...
Definition: test_cdr.c:208
#define ast_channel_unlock(chan)
Definition: channel.h:2946
static struct ast_cdr_config unanswered_cdr_config
A configuration suitable for CDRs with unanswered records.
Definition: test_cdr.c:66
#define ast_free(a)
Definition: astmm.h:182
#define ast_calloc(num, len)
A wrapper for calloc()
Definition: astmm.h:204
struct ast_cdr_config * ast_cdr_get_config(void)
Obtain the current CDR configuration.
Definition: cdr.c:2826
struct ast_var_t::@249 entries
#define ast_var_assign(name, value)
Definition: chanvars.h:40
void ast_hangup(struct ast_channel *chan)
Hang up a channel.
Definition: channel.c:2548
#define CHANNEL_TECH_NAME
Definition: test_cdr.c:55
static struct ast_channel_tech test_cdr_chan_tech
A channel technology used for the unit tests.
Definition: test_cdr.c:91
Basic bridge subclass API.
void ast_cdr_setuserfield(const char *channel_name, const char *userfield)
Set CDR user field for channel (stored in CDR)
Definition: cdr.c:3477
Structure used to handle boolean flags.
Definition: utils.h:199
#define ast_clear_flag(p, flag)
Definition: utils.h:77
void ast_channel_exten_set(struct ast_channel *chan, const char *value)
struct ast_bridge * ast_bridge_basic_new(void)
Create a new basic class bridge.
#define AST_CAUSE_NO_ROUTE_DESTINATION
Definition: causes.h:99
Definition: test.c:65
#define ao2_cleanup(obj)
Definition: astobj2.h:1958
void ast_channel_context_set(struct ast_channel *chan, const char *value)
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:401
static void safe_bridge_destroy(struct ast_bridge *bridge)
Definition: test_cdr.c:379
#define S_OR(a, b)
returns the equivalent of logic or for strings: first one if not empty, otherwise second one...
Definition: strings.h:79
const char * ast_channel_name(const struct ast_channel *chan)
void ast_channel_state_set(struct ast_channel *chan, enum ast_channel_state)
int ast_setstate(struct ast_channel *chan, enum ast_channel_state)
Change the state of a channel.
Definition: channel.c:7486
static PGresult * result
Definition: cel_pgsql.c:88
#define AST_CAUSE_BUSY
Definition: causes.h:148
void ast_cdr_free(struct ast_cdr *cdr)
Free a CDR record.
Definition: cdr.c:3411
Internal Asterisk hangup causes.
int ast_cdr_clear_property(const char *channel_name, enum ast_cdr_options option)
Clear a property on a CDR for a channel.
Definition: cdr.c:3575
#define BOB_CALLERID
Bob&#39;s Caller ID.
Definition: test_cdr.c:219
The global options available for CDRs.
Definition: cdr.h:264
void ast_channel_publish_snapshot(struct ast_channel *chan)
Publish a ast_channel_snapshot for a channel.
char clid[AST_MAX_EXTENSION]
Definition: cdr.h:278
struct ast_flags * ast_channel_flags(struct ast_channel *chan)
static struct ast_cdr_config debug_cdr_config
A configuration suitable for &#39;normal&#39; CDRs.
Definition: test_cdr.c:61
#define AST_LIST_HEAD_INIT_VALUE
Defines initial values for a declaration of AST_LIST_HEAD.
Definition: linkedlists.h:233
#define ASTERISK_GPL_KEY
The text the key() function should return.
Definition: module.h:46
void ast_channel_priority_set(struct ast_channel *chan, int value)
Bridging API.
#define ast_channel_alloc(needqueue, state, cid_num, cid_name, acctcode, exten, context, assignedids, requestor, amaflag,...)
Create a channel structure.
Definition: channel.h:1259
Asterisk module definitions.
#define VERIFY_STRING_FIELD(field, actual, expected)
Verify a string field. This will set the test status result to fail; as such, it assumes that (a) tes...
Definition: test_cdr.c:186
#define VERIFY_NUMERIC_FIELD(field, actual, expected)
Verify a numeric field. This will set the test status result to fail; as such, it assumes that (a) te...
Definition: test_cdr.c:197
#define ast_cond_timedwait(cond, mutex, time)
Definition: lock.h:204
#define AST_CAUSE_CONGESTION
Definition: causes.h:152
void ast_channel_data_set(struct ast_channel *chan, const char *value)
static void safe_channel_release(struct ast_channel *chan)
Definition: test_cdr.c:371
ast_test_result_state
Definition: test.h:200
Media Format Cache API.
static int global_mock_cdr_count
The number of CDRs the mock backend has received.
Definition: test_cdr.c:102