Asterisk - The Open Source Telephony Project GIT-master-b023714
Loading...
Searching...
No Matches
Data Structures | Macros | Functions | Variables
test_cdr.c File Reference

CDR unit tests. More...

#include "asterisk.h"
#include <math.h>
#include "asterisk/module.h"
#include "asterisk/test.h"
#include "asterisk/cdr.h"
#include "asterisk/linkedlists.h"
#include "asterisk/chanvars.h"
#include "asterisk/utils.h"
#include "asterisk/causes.h"
#include "asterisk/time.h"
#include "asterisk/bridge.h"
#include "asterisk/bridge_basic.h"
#include "asterisk/stasis_channels.h"
#include "asterisk/stasis_bridges.h"
#include "asterisk/format_cache.h"
Include dependency graph for test_cdr.c:

Go to the source code of this file.

Data Structures

struct  test_cdr_entry
 

Macros

#define ALICE_CALLERID   { .id.name.str = "Alice", .id.name.valid = 1, .id.number.str = "100", .id.number.valid = 1, }
 Alice's Caller ID.
 
#define BOB_CALLERID   { .id.name.str = "Bob", .id.name.valid = 1, .id.number.str = "200", .id.number.valid = 1, }
 Bob's Caller ID.
 
#define CHANNEL_TECH_NAME   "CDRTestChannel"
 
#define CHARLIE_CALLERID   { .id.name.str = "Charlie", .id.name.valid = 1, .id.number.str = "300", .id.number.valid = 1, }
 Charlie's Caller ID.
 
#define COPY_IDS(channel_var, expected_record)
 Copy the linkedid and uniqueid from a channel to an expected CDR.
 
#define CREATE_ALICE_CHANNEL(channel_var, caller_id, expected_record)
 Create a test_cdr_chan_tech for Alice, and set the expected CDR records' linkedid and uniqueid.
 
#define CREATE_BOB_CHANNEL(channel_var, caller_id, expected_record)
 Create a test_cdr_chan_tech for Bob, and set the expected CDR records' linkedid and uniqueid.
 
#define CREATE_CHARLIE_CHANNEL(channel_var, caller_id, expected_record)
 Create a test_cdr_chan_tech for Charlie, and set the expected CDR records' linkedid and uniqueid.
 
#define CREATE_DAVID_CHANNEL(channel_var, caller_id, expected_record)
 Create a test_cdr_chan_tech for Charlie, and set the expected CDR records' linkedid and uniqueid.
 
#define DAVID_CALLERID   { .id.name.str = "David", .id.name.valid = 1, .id.number.str = "400", .id.number.valid = 1, }
 David's Caller ID.
 
#define EMULATE_APP_DATA(channel, priority, application, data)
 Emulate a channel entering into an application.
 
#define EPSILON   0.001
 
#define HANGUP_CHANNEL(channel, cause)
 Hang up a test channel safely.
 
#define MOCK_CDR_BACKEND   "mock_cdr_backend"
 
#define SET_FORMATS(chan)
 Set ulaw format on channel.
 
#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 test to set the needed configuration for that test.
 
#define TEST_CATEGORY   "/main/cdr/"
 
#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) test is the test object variable, and (b) that a return variable res exists.
 
#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) test is the test object variable, and (b) that a return variable res exists.
 
#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 is the test object variable, and (b) that a return variable res exists.
 

Functions

static void __reg_module (void)
 
static void __unreg_module (void)
 
struct ast_moduleAST_MODULE_SELF_SYM (void)
 
 AST_TEST_DEFINE (test_cdr_channel_creation)
 
 AST_TEST_DEFINE (test_cdr_dial_answer_multiparty)
 
 AST_TEST_DEFINE (test_cdr_dial_answer_no_bridge)
 
 AST_TEST_DEFINE (test_cdr_dial_answer_twoparty_bridge_a)
 
 AST_TEST_DEFINE (test_cdr_dial_answer_twoparty_bridge_b)
 
 AST_TEST_DEFINE (test_cdr_dial_busy)
 
 AST_TEST_DEFINE (test_cdr_dial_caller_cancel)
 
 AST_TEST_DEFINE (test_cdr_dial_congestion)
 
 AST_TEST_DEFINE (test_cdr_dial_parallel_failed)
 
 AST_TEST_DEFINE (test_cdr_dial_unanswered)
 
 AST_TEST_DEFINE (test_cdr_dial_unavailable)
 
 AST_TEST_DEFINE (test_cdr_fields)
 
 AST_TEST_DEFINE (test_cdr_fork_cdr)
 
 AST_TEST_DEFINE (test_cdr_no_reset_cdr)
 
 AST_TEST_DEFINE (test_cdr_outbound_bridged_call)
 
 AST_TEST_DEFINE (test_cdr_park)
 
 AST_TEST_DEFINE (test_cdr_single_bridge)
 
 AST_TEST_DEFINE (test_cdr_single_bridge_continue)
 
 AST_TEST_DEFINE (test_cdr_single_multiparty_bridge)
 
 AST_TEST_DEFINE (test_cdr_single_party)
 
 AST_TEST_DEFINE (test_cdr_single_twoparty_bridge_a)
 
 AST_TEST_DEFINE (test_cdr_single_twoparty_bridge_b)
 
 AST_TEST_DEFINE (test_cdr_unanswered_inbound_call)
 
 AST_TEST_DEFINE (test_cdr_unanswered_outbound_call)
 
static void clear_mock_cdr_backend (void)
 
static void do_sleep (struct timespec *to_sleep)
 
static int load_module (void)
 
static int mock_cdr_backend_cb (struct ast_cdr *cdr)
 
static void safe_bridge_destroy (struct ast_bridge *bridge)
 
static void safe_channel_release (struct ast_channel *chan)
 
static int test_cdr_cleanup_cb (struct ast_test_info *info, struct ast_test *test)
 
static int test_cdr_init_cb (struct ast_test_info *info, struct ast_test *test)
 
static int unload_module (void)
 
static enum ast_test_result_state verify_mock_cdr_record (struct ast_test *test, struct ast_cdr *expected, int record)
 

Variables

static struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_LOAD_ORDER , .description = "CDR unit tests" , .key = ASTERISK_GPL_KEY , .buildopt_sum = AST_BUILDOPT_SUM, .load = load_module, .unload = unload_module, .load_pri = AST_MODPRI_DEFAULT, .support_level = AST_MODULE_SUPPORT_CORE, }
 
struct { 
 
   struct test_cdr_entry *   first 
 
   struct test_cdr_entry *   last 
 
   ast_mutex_t   lock 
 
actual_cdr_entries = AST_LIST_HEAD_INIT_VALUE 
 A linked list of received CDR entries from the engine.
 
static const struct ast_module_infoast_module_info = &__mod_info
 
static struct ast_cdr_config congestion_cdr_config
 A configuration suitable for CDRs with congestion enabled.
 
static struct ast_cdr_config debug_cdr_config
 A configuration suitable for 'normal' CDRs.
 
static int global_mock_cdr_count
 The number of CDRs the mock backend has received.
 
static ast_cond_t mock_cdr_cond
 The Mock CDR backend condition wait.
 
static struct ast_cdr_configsaved_config
 A placeholder for Asterisk's 'real' CDR configuration.
 
static struct ast_channel_tech test_cdr_chan_tech
 A channel technology used for the unit tests.
 
static struct ast_cdr_config unanswered_cdr_config
 A configuration suitable for CDRs with unanswered records.
 

Detailed Description

CDR unit tests.

Author
Matt Jordan mjord.nosp@m.an@d.nosp@m.igium.nosp@m..com

Definition in file test_cdr.c.

Macro Definition Documentation

◆ ALICE_CALLERID

#define ALICE_CALLERID   { .id.name.str = "Alice", .id.name.valid = 1, .id.number.str = "100", .id.number.valid = 1, }

Alice's Caller ID.

Definition at line 216 of file test_cdr.c.

◆ BOB_CALLERID

#define BOB_CALLERID   { .id.name.str = "Bob", .id.name.valid = 1, .id.number.str = "200", .id.number.valid = 1, }

Bob's Caller ID.

Definition at line 219 of file test_cdr.c.

◆ CHANNEL_TECH_NAME

#define CHANNEL_TECH_NAME   "CDRTestChannel"

Definition at line 55 of file test_cdr.c.

◆ CHARLIE_CALLERID

#define CHARLIE_CALLERID   { .id.name.str = "Charlie", .id.name.valid = 1, .id.number.str = "300", .id.number.valid = 1, }

Charlie's Caller ID.

Definition at line 222 of file test_cdr.c.

◆ COPY_IDS

#define COPY_IDS (   channel_var,
  expected_record 
)
Value:
do { \
ast_copy_string((expected_record)->uniqueid, ast_channel_uniqueid((channel_var)), sizeof((expected_record)->uniqueid)); \
ast_copy_string((expected_record)->linkedid, ast_channel_linkedid((channel_var)), sizeof((expected_record)->linkedid)); \
} while (0)
const char * ast_channel_linkedid(const struct ast_channel *chan)
const char * ast_channel_uniqueid(const struct ast_channel *chan)

Copy the linkedid and uniqueid from a channel to an expected CDR.

Definition at line 228 of file test_cdr.c.

228 { \
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)

◆ CREATE_ALICE_CHANNEL

#define CREATE_ALICE_CHANNEL (   channel_var,
  caller_id,
  expected_record 
)

Create a test_cdr_chan_tech for Alice, and set the expected CDR records' linkedid and uniqueid.

Definition at line 248 of file test_cdr.c.

248 { \
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)
#define ast_channel_alloc(needqueue, state, cid_num, cid_name, acctcode, exten, context, assignedids, requestor, amaflag,...)
Create a channel structure.
Definition channel.h:1299
@ AST_STATE_DOWN
#define NULL
Definition resample.c:96
#define CHANNEL_TECH_NAME
Definition test_cdr.c:55

◆ CREATE_BOB_CHANNEL

#define CREATE_BOB_CHANNEL (   channel_var,
  caller_id,
  expected_record 
)

Create a test_cdr_chan_tech for Bob, and set the expected CDR records' linkedid and uniqueid.

Definition at line 259 of file test_cdr.c.

259 { \
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)

◆ CREATE_CHARLIE_CHANNEL

#define CREATE_CHARLIE_CHANNEL (   channel_var,
  caller_id,
  expected_record 
)

Create a test_cdr_chan_tech for Charlie, and set the expected CDR records' linkedid and uniqueid.

Definition at line 270 of file test_cdr.c.

270 { \
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)

◆ CREATE_DAVID_CHANNEL

#define CREATE_DAVID_CHANNEL (   channel_var,
  caller_id,
  expected_record 
)

Create a test_cdr_chan_tech for Charlie, and set the expected CDR records' linkedid and uniqueid.

Definition at line 281 of file test_cdr.c.

281 { \
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)

◆ DAVID_CALLERID

#define DAVID_CALLERID   { .id.name.str = "David", .id.name.valid = 1, .id.number.str = "400", .id.number.valid = 1, }

David's Caller ID.

Definition at line 225 of file test_cdr.c.

◆ EMULATE_APP_DATA

#define EMULATE_APP_DATA (   channel,
  priority,
  application,
  data 
)

Emulate a channel entering into an application.

Definition at line 291 of file test_cdr.c.

291 { \
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)
static int priority

◆ EPSILON

#define EPSILON   0.001

Definition at line 49 of file test_cdr.c.

◆ HANGUP_CHANNEL

#define HANGUP_CHANNEL (   channel,
  cause 
)
Value:
do { \
ast_channel_hangupcause_set((channel), (cause)); \
ast_hangup(channel); \
channel = NULL; \
} while (0)

Hang up a test channel safely.

Definition at line 303 of file test_cdr.c.

304 { \
305 ast_channel_hangupcause_set((channel), (cause)); \
306 ast_hangup(channel); \
307 channel = NULL; \
308 } while (0)

◆ MOCK_CDR_BACKEND

#define MOCK_CDR_BACKEND   "mock_cdr_backend"

Definition at line 53 of file test_cdr.c.

◆ SET_FORMATS

#define SET_FORMATS (   chan)

Set ulaw format on channel.

Definition at line 234 of file test_cdr.c.

234 {\
235 struct ast_format_cap *caps;\
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)
struct ast_format * ast_format_ulaw
Built-in cached ulaw format.
@ AST_FORMAT_CAP_FLAG_DEFAULT
Definition format_cap.h:38
#define ast_format_cap_alloc(flags)
Allocate a new ast_format_cap structure.
Definition format_cap.h:49
Format capabilities structure, holds formats + preference order + etc.
Definition format_cap.c:54

◆ SWAP_CONFIG

#define SWAP_CONFIG (   ao2_config,
  template 
)
Value:
do { \
*(ao2_config) = (template); \
ast_cdr_set_config((ao2_config)); \
} while (0)

Macro to swap a configuration out from the CDR engine. This should be used at the beginning of each test to set the needed configuration for that test.

Definition at line 79 of file test_cdr.c.

79 { \
80 *(ao2_config) = (template); \
81 ast_cdr_set_config((ao2_config)); \
82 } while (0)

◆ TEST_CATEGORY

#define TEST_CATEGORY   "/main/cdr/"

Definition at line 51 of file test_cdr.c.

◆ VERIFY_NUMERIC_FIELD

#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) test is the test object variable, and (b) that a return variable res exists.

Definition at line 197 of file test_cdr.c.

197 { \
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)
@ AST_TEST_FAIL
Definition test.h:196

◆ VERIFY_STRING_FIELD

#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) test is the test object variable, and (b) that a return variable res exists.

Definition at line 186 of file test_cdr.c.

186 { \
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)

◆ VERIFY_TIME_VALUE

#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 is the test object variable, and (b) that a return variable res exists.

Definition at line 208 of file test_cdr.c.

208 { \
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)
int ast_tvzero(const struct timeval t)
Returns true if the argument is 0,0.
Definition time.h:117

Function Documentation

◆ __reg_module()

static void __reg_module ( void  )
static

Definition at line 2628 of file test_cdr.c.

◆ __unreg_module()

static void __unreg_module ( void  )
static

Definition at line 2628 of file test_cdr.c.

◆ AST_MODULE_SELF_SYM()

struct ast_module * AST_MODULE_SELF_SYM ( void  )

Definition at line 2628 of file test_cdr.c.

◆ AST_TEST_DEFINE() [1/24]

AST_TEST_DEFINE ( test_cdr_channel_creation  )

Definition at line 393 of file test_cdr.c.

394{
396 RAII_VAR(struct ast_cdr_config *, config, ao2_alloc(sizeof(*config), NULL),
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
425
426 CREATE_ALICE_CHANNEL(chan, (&caller), &expected);
427
429
430 result = verify_mock_cdr_record(test, &expected, 1);
431
432 return result;
433}
#define ao2_cleanup(obj)
Definition astobj2.h:1934
#define ao2_alloc(data_size, destructor_fn)
Definition astobj2.h:409
#define AST_CAUSE_NORMAL
Definition causes.h:151
@ AST_CDR_NOANSWER
Definition cdr.h:258
static PGresult * result
Definition cel_pgsql.c:84
static const char config[]
@ AST_AMA_DOCUMENTATION
Definition channel.h:1201
The global options available for CDRs.
Definition cdr.h:269
Responsible for call detail data.
Definition cdr.h:281
char clid[AST_MAX_EXTENSION]
Definition cdr.h:283
struct timeval start
Definition cdr.h:299
Main Channel structure associated with a channel.
Caller Party information.
Definition channel.h:420
@ TEST_INIT
Definition test.h:200
@ TEST_EXECUTE
Definition test.h:201
ast_test_result_state
Definition test.h:193
@ AST_TEST_NOT_RUN
Definition test.h:194
#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
#define CREATE_ALICE_CHANNEL(channel_var, caller_id, expected_record)
Create a test_cdr_chan_tech for Alice, and set the expected CDR records' linkedid and uniqueid.
Definition test_cdr.c:248
static struct ast_cdr_config unanswered_cdr_config
A configuration suitable for CDRs with unanswered records.
Definition test_cdr.c:66
#define ALICE_CALLERID
Alice's Caller ID.
Definition test_cdr.c:216
static void safe_channel_release(struct ast_channel *chan)
Definition test_cdr.c:371
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
#define HANGUP_CHANNEL(channel, cause)
Hang up a test channel safely.
Definition test_cdr.c:303
#define TEST_CATEGORY
Definition test_cdr.c:51
#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:978

References ALICE_CALLERID, ao2_alloc, ao2_cleanup, AST_AMA_DOCUMENTATION, AST_CAUSE_NORMAL, AST_CDR_NOANSWER, AST_TEST_NOT_RUN, CHANNEL_TECH_NAME, ast_cdr::clid, config, CREATE_ALICE_CHANNEL, HANGUP_CHANNEL, NULL, RAII_VAR, result, safe_channel_release(), ast_cdr::start, SWAP_CONFIG, TEST_CATEGORY, TEST_EXECUTE, TEST_INIT, unanswered_cdr_config, and verify_mock_cdr_record().

◆ AST_TEST_DEFINE() [2/24]

AST_TEST_DEFINE ( test_cdr_dial_answer_multiparty  )

Definition at line 1840 of file test_cdr.c.

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
1963
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");
1974 EMULATE_APP_DATA(chan_bob, 0, "AppDial", "(Outgoing Line)");
1977
1979 EMULATE_APP_DATA(chan_charlie, 1, "Dial", CHANNEL_TECH_NAME "/David");
1984
1985 chan_david = ast_channel_alloc(0, AST_STATE_DOWN, "400", "David", "400", "400", "default", NULL, NULL, 0, CHANNEL_TECH_NAME "/David");
1989 EMULATE_APP_DATA(chan_david, 0, "AppDial", "(Outgoing Line)");
1990
1997
2002
2003 bridge = ast_bridge_basic_new();
2004 ast_test_validate(test, bridge != NULL);
2005
2019
2024
2026
2027 return result;
2028}
int ast_bridge_depart(struct ast_channel *chan)
Depart a channel from a bridge.
Definition bridge.c:1975
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:1947
@ AST_BRIDGE_IMPART_CHAN_DEPARTABLE
Definition bridge.h:592
struct ast_bridge * ast_bridge_basic_new(void)
Create a new basic class bridge.
@ AST_CDR_ANSWERED
Definition cdr.h:262
struct ast_flags * ast_channel_flags(struct ast_channel *chan)
void ast_channel_state_set(struct ast_channel *chan, enum ast_channel_state)
@ AST_FLAG_OUTGOING
Definition channel.h:1019
#define ast_channel_unlock(chan)
Definition channel.h:2983
@ AST_STATE_RINGING
@ AST_STATE_UP
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_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition strings.h:425
Structure that contains information about a bridge.
Definition bridge.h:353
#define COPY_IDS(channel_var, expected_record)
Copy the linkedid and uniqueid from a channel to an expected CDR.
Definition test_cdr.c:228
static void safe_bridge_destroy(struct ast_bridge *bridge)
Definition test_cdr.c:379
#define SET_FORMATS(chan)
Set ulaw format on channel.
Definition test_cdr.c:234
#define CREATE_CHARLIE_CHANNEL(channel_var, caller_id, expected_record)
Create a test_cdr_chan_tech for Charlie, and set the expected CDR records' linkedid and uniqueid.
Definition test_cdr.c:270
#define EMULATE_APP_DATA(channel, priority, application, data)
Emulate a channel entering into an application.
Definition test_cdr.c:291
static struct ast_cdr_config debug_cdr_config
A configuration suitable for 'normal' CDRs.
Definition test_cdr.c:61
#define CHARLIE_CALLERID
Charlie's Caller ID.
Definition test_cdr.c:222
static void do_sleep(void)
Definition test_cel.c:87
static struct timespec to_sleep
A 1 second sleep.
Definition test_cel.c:85
#define ast_set_flag(p, flag)
Definition utils.h:70

References ALICE_CALLERID, ao2_alloc, ao2_cleanup, AST_AMA_DOCUMENTATION, ast_bridge_basic_new(), ast_bridge_depart(), ast_bridge_impart(), AST_BRIDGE_IMPART_CHAN_DEPARTABLE, AST_CAUSE_NORMAL, AST_CDR_ANSWERED, ast_channel_alloc, ast_channel_flags(), ast_channel_linkedid(), ast_channel_publish_dial(), ast_channel_state_set(), ast_channel_uniqueid(), ast_channel_unlock, ast_copy_string(), AST_FLAG_OUTGOING, ast_set_flag, AST_STATE_DOWN, AST_STATE_RINGING, AST_STATE_UP, AST_TEST_NOT_RUN, CHANNEL_TECH_NAME, CHARLIE_CALLERID, ast_cdr::clid, config, COPY_IDS, CREATE_ALICE_CHANNEL, CREATE_CHARLIE_CHANNEL, debug_cdr_config, do_sleep(), EMULATE_APP_DATA, HANGUP_CHANNEL, NULL, RAII_VAR, result, safe_bridge_destroy(), safe_channel_release(), SET_FORMATS, ast_cdr::start, SWAP_CONFIG, TEST_CATEGORY, TEST_EXECUTE, TEST_INIT, to_sleep, and verify_mock_cdr_record().

◆ AST_TEST_DEFINE() [3/24]

AST_TEST_DEFINE ( test_cdr_dial_answer_no_bridge  )

Definition at line 1589 of file test_cdr.c.

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
1658
1661
1663
1669
1673
1677
1678 EMULATE_APP_DATA(chan_caller, 2, "Wait", "1");
1679 EMULATE_APP_DATA(chan_callee, 1, "Wait", "1");
1680
1683
1685 return result;
1686}
#define ast_clear_flag(p, flag)
Definition utils.h:77

References ALICE_CALLERID, ao2_alloc, ao2_cleanup, AST_AMA_DOCUMENTATION, AST_CAUSE_NORMAL, AST_CDR_ANSWERED, ast_channel_alloc, ast_channel_flags(), ast_channel_publish_dial(), ast_channel_state_set(), ast_channel_unlock, ast_clear_flag, AST_FLAG_OUTGOING, ast_set_flag, AST_STATE_DOWN, AST_STATE_RINGING, AST_STATE_UP, AST_TEST_NOT_RUN, CHANNEL_TECH_NAME, ast_cdr::clid, config, COPY_IDS, CREATE_ALICE_CHANNEL, debug_cdr_config, EMULATE_APP_DATA, HANGUP_CHANNEL, NULL, RAII_VAR, result, safe_channel_release(), SET_FORMATS, ast_cdr::start, SWAP_CONFIG, TEST_CATEGORY, TEST_EXECUTE, TEST_INIT, and verify_mock_cdr_record().

◆ AST_TEST_DEFINE() [4/24]

AST_TEST_DEFINE ( test_cdr_dial_answer_twoparty_bridge_a  )

Definition at line 1688 of file test_cdr.c.

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
1728
1729 CREATE_ALICE_CHANNEL(chan_caller, &caller, &expected);
1730
1732
1737 EMULATE_APP_DATA(chan_callee, 0, "AppDial", "(Outgoing Line)");
1738
1742
1745
1746 bridge = ast_bridge_basic_new();
1747 ast_test_validate(test, bridge != NULL);
1749
1752
1754
1757
1760
1761 result = verify_mock_cdr_record(test, &expected, 1);
1762 return result;
1763}

References ALICE_CALLERID, ao2_alloc, ao2_cleanup, AST_AMA_DOCUMENTATION, ast_bridge_basic_new(), ast_bridge_depart(), ast_bridge_impart(), AST_BRIDGE_IMPART_CHAN_DEPARTABLE, AST_CAUSE_NORMAL, AST_CDR_ANSWERED, ast_channel_alloc, ast_channel_flags(), ast_channel_publish_dial(), ast_channel_state_set(), ast_channel_unlock, AST_FLAG_OUTGOING, ast_set_flag, AST_STATE_DOWN, AST_STATE_RINGING, AST_STATE_UP, AST_TEST_NOT_RUN, CHANNEL_TECH_NAME, ast_cdr::clid, config, CREATE_ALICE_CHANNEL, debug_cdr_config, do_sleep(), EMULATE_APP_DATA, HANGUP_CHANNEL, NULL, RAII_VAR, result, safe_bridge_destroy(), safe_channel_release(), SET_FORMATS, ast_cdr::start, SWAP_CONFIG, TEST_CATEGORY, TEST_EXECUTE, TEST_INIT, to_sleep, and verify_mock_cdr_record().

◆ AST_TEST_DEFINE() [5/24]

AST_TEST_DEFINE ( test_cdr_dial_answer_twoparty_bridge_b  )

Definition at line 1765 of file test_cdr.c.

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
1805
1806 CREATE_ALICE_CHANNEL(chan_caller, &caller, &expected);
1807
1809
1814 EMULATE_APP_DATA(chan_callee, 0, "AppDial", "(Outgoing Line)");
1815
1819
1822
1823 bridge = ast_bridge_basic_new();
1824 ast_test_validate(test, bridge != NULL);
1832
1835
1836 result = verify_mock_cdr_record(test, &expected, 1);
1837 return result;
1838}

References ALICE_CALLERID, ao2_alloc, ao2_cleanup, AST_AMA_DOCUMENTATION, ast_bridge_basic_new(), ast_bridge_depart(), ast_bridge_impart(), AST_BRIDGE_IMPART_CHAN_DEPARTABLE, AST_CAUSE_NORMAL, AST_CDR_ANSWERED, ast_channel_alloc, ast_channel_flags(), ast_channel_publish_dial(), ast_channel_state_set(), ast_channel_unlock, AST_FLAG_OUTGOING, ast_set_flag, AST_STATE_DOWN, AST_STATE_RINGING, AST_STATE_UP, AST_TEST_NOT_RUN, CHANNEL_TECH_NAME, ast_cdr::clid, config, CREATE_ALICE_CHANNEL, debug_cdr_config, do_sleep(), EMULATE_APP_DATA, HANGUP_CHANNEL, NULL, RAII_VAR, result, safe_bridge_destroy(), safe_channel_release(), SET_FORMATS, ast_cdr::start, SWAP_CONFIG, TEST_CATEGORY, TEST_EXECUTE, TEST_INIT, to_sleep, and verify_mock_cdr_record().

◆ AST_TEST_DEFINE() [6/24]

AST_TEST_DEFINE ( test_cdr_dial_busy  )

Definition at line 1211 of file test_cdr.c.

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
1250
1251 CREATE_ALICE_CHANNEL(chan_caller, &caller, &expected);
1252
1254
1259 EMULATE_APP_DATA(chan_callee, 0, "AppDial", "(Outgoing Line)");
1260
1264
1267
1268 result = verify_mock_cdr_record(test, &expected, 1);
1269
1270 return result;
1271}
#define AST_CAUSE_BUSY
Definition causes.h:149
@ AST_CDR_BUSY
Definition cdr.h:261

References ALICE_CALLERID, ao2_alloc, ao2_cleanup, AST_AMA_DOCUMENTATION, AST_CAUSE_BUSY, AST_CDR_BUSY, ast_channel_alloc, ast_channel_flags(), ast_channel_publish_dial(), ast_channel_state_set(), ast_channel_unlock, AST_FLAG_OUTGOING, ast_set_flag, AST_STATE_DOWN, AST_STATE_RINGING, AST_TEST_NOT_RUN, CHANNEL_TECH_NAME, ast_cdr::clid, config, CREATE_ALICE_CHANNEL, EMULATE_APP_DATA, HANGUP_CHANNEL, NULL, RAII_VAR, result, safe_channel_release(), SET_FORMATS, ast_cdr::start, SWAP_CONFIG, TEST_CATEGORY, TEST_EXECUTE, TEST_INIT, unanswered_cdr_config, and verify_mock_cdr_record().

◆ AST_TEST_DEFINE() [7/24]

AST_TEST_DEFINE ( test_cdr_dial_caller_cancel  )

Definition at line 1397 of file test_cdr.c.

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
1437
1438 CREATE_ALICE_CHANNEL(chan_caller, &caller, &expected);
1439
1441
1446 EMULATE_APP_DATA(chan_callee, 0, "AppDial", "(Outgoing Line)");
1447
1451
1454
1455 result = verify_mock_cdr_record(test, &expected, 1);
1456
1457 return result;
1458}

References ALICE_CALLERID, ao2_alloc, ao2_cleanup, AST_AMA_DOCUMENTATION, AST_CAUSE_NORMAL, AST_CDR_NOANSWER, ast_channel_alloc, ast_channel_flags(), ast_channel_publish_dial(), ast_channel_state_set(), ast_channel_unlock, AST_FLAG_OUTGOING, ast_set_flag, AST_STATE_DOWN, AST_STATE_RINGING, AST_TEST_NOT_RUN, CHANNEL_TECH_NAME, ast_cdr::clid, config, CREATE_ALICE_CHANNEL, EMULATE_APP_DATA, HANGUP_CHANNEL, NULL, RAII_VAR, result, safe_channel_release(), SET_FORMATS, ast_cdr::start, SWAP_CONFIG, TEST_CATEGORY, TEST_EXECUTE, TEST_INIT, unanswered_cdr_config, and verify_mock_cdr_record().

◆ AST_TEST_DEFINE() [8/24]

AST_TEST_DEFINE ( test_cdr_dial_congestion  )

Definition at line 1273 of file test_cdr.c.

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
1312
1313 CREATE_ALICE_CHANNEL(chan_caller, &caller, &expected);
1314
1316
1321 EMULATE_APP_DATA(chan_callee, 0, "AppDial", "(Outgoing Line)");
1322
1326
1329
1330 result = verify_mock_cdr_record(test, &expected, 1);
1331
1332 return result;
1333}
#define AST_CAUSE_CONGESTION
Definition causes.h:153
@ AST_CDR_CONGESTION
Definition cdr.h:263
static struct ast_cdr_config congestion_cdr_config
A configuration suitable for CDRs with congestion enabled.
Definition test_cdr.c:71

References ALICE_CALLERID, ao2_alloc, ao2_cleanup, AST_AMA_DOCUMENTATION, AST_CAUSE_CONGESTION, AST_CDR_CONGESTION, ast_channel_alloc, ast_channel_flags(), ast_channel_publish_dial(), ast_channel_state_set(), ast_channel_unlock, AST_FLAG_OUTGOING, ast_set_flag, AST_STATE_DOWN, AST_STATE_RINGING, AST_TEST_NOT_RUN, CHANNEL_TECH_NAME, ast_cdr::clid, config, congestion_cdr_config, CREATE_ALICE_CHANNEL, EMULATE_APP_DATA, HANGUP_CHANNEL, NULL, RAII_VAR, result, safe_channel_release(), SET_FORMATS, ast_cdr::start, SWAP_CONFIG, TEST_CATEGORY, TEST_EXECUTE, TEST_INIT, and verify_mock_cdr_record().

◆ AST_TEST_DEFINE() [9/24]

AST_TEST_DEFINE ( test_cdr_dial_parallel_failed  )

Definition at line 1460 of file test_cdr.c.

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;
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
1536
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 */
1549 EMULATE_APP_DATA(chan_bob, 0, "AppDial", "(Outgoing Line)");
1550
1555 EMULATE_APP_DATA(chan_charlie, 0, "AppDial", "(Outgoing Line)");
1556
1561 EMULATE_APP_DATA(chan_david, 0, "AppDial", "(Outgoing Line)");
1562
1563 /* Dial starts */
1568
1569 /* Charlie is busy */
1572
1573 /* David is congested */
1576
1577 /* Bob is canceled */
1580
1581 /* Alice hangs up */
1583
1584 result = verify_mock_cdr_record(test, expected, 3);
1585
1586 return result;
1587}
struct ast_cdr * next
Definition cdr.h:334

References ALICE_CALLERID, ao2_alloc, ao2_cleanup, AST_AMA_DOCUMENTATION, AST_CAUSE_BUSY, AST_CAUSE_CONGESTION, AST_CAUSE_NORMAL, AST_CDR_BUSY, AST_CDR_CONGESTION, AST_CDR_NOANSWER, ast_channel_alloc, ast_channel_flags(), ast_channel_publish_dial(), ast_channel_state_set(), ast_channel_unlock, AST_FLAG_OUTGOING, ast_set_flag, AST_STATE_DOWN, AST_STATE_RINGING, AST_TEST_NOT_RUN, CHANNEL_TECH_NAME, ast_cdr::clid, config, congestion_cdr_config, COPY_IDS, CREATE_ALICE_CHANNEL, EMULATE_APP_DATA, HANGUP_CHANNEL, ast_cdr::next, NULL, RAII_VAR, result, safe_channel_release(), SET_FORMATS, ast_cdr::start, SWAP_CONFIG, TEST_CATEGORY, TEST_EXECUTE, TEST_INIT, and verify_mock_cdr_record().

◆ AST_TEST_DEFINE() [10/24]

AST_TEST_DEFINE ( test_cdr_dial_unanswered  )

Definition at line 1148 of file test_cdr.c.

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
1187
1188 CREATE_ALICE_CHANNEL(chan_caller, &caller, &expected);
1189
1190 EMULATE_APP_DATA(chan_caller, 1, "Dial", "CDRTestChannel/Bob");
1191
1196 EMULATE_APP_DATA(chan_callee, 0, "AppDial", "(Outgoing Line)");
1197
1201
1204
1205 result = verify_mock_cdr_record(test, &expected, 1);
1206
1207 return result;
1208}
#define AST_CAUSE_NO_ANSWER
Definition causes.h:109

References ALICE_CALLERID, ao2_alloc, ao2_cleanup, AST_AMA_DOCUMENTATION, AST_CAUSE_NO_ANSWER, AST_CDR_NOANSWER, ast_channel_alloc, ast_channel_flags(), ast_channel_publish_dial(), ast_channel_state_set(), ast_channel_unlock, AST_FLAG_OUTGOING, ast_set_flag, AST_STATE_DOWN, AST_STATE_RINGING, AST_TEST_NOT_RUN, CHANNEL_TECH_NAME, ast_cdr::clid, config, CREATE_ALICE_CHANNEL, EMULATE_APP_DATA, HANGUP_CHANNEL, NULL, RAII_VAR, result, safe_channel_release(), SET_FORMATS, ast_cdr::start, SWAP_CONFIG, TEST_CATEGORY, TEST_EXECUTE, TEST_INIT, unanswered_cdr_config, and verify_mock_cdr_record().

◆ AST_TEST_DEFINE() [11/24]

AST_TEST_DEFINE ( test_cdr_dial_unavailable  )

Definition at line 1335 of file test_cdr.c.

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
1374
1375 CREATE_ALICE_CHANNEL(chan_caller, &caller, &expected);
1376
1378
1383 EMULATE_APP_DATA(chan_callee, 0, "AppDial", "(Outgoing Line)");
1384
1388
1391
1392 result = verify_mock_cdr_record(test, &expected, 1);
1393
1394 return result;
1395}
#define AST_CAUSE_NO_ROUTE_DESTINATION
Definition causes.h:100
@ AST_CDR_FAILED
Definition cdr.h:260

References ALICE_CALLERID, ao2_alloc, ao2_cleanup, AST_AMA_DOCUMENTATION, AST_CAUSE_NO_ROUTE_DESTINATION, AST_CDR_FAILED, ast_channel_alloc, ast_channel_flags(), ast_channel_publish_dial(), ast_channel_state_set(), ast_channel_unlock, AST_FLAG_OUTGOING, ast_set_flag, AST_STATE_DOWN, AST_STATE_RINGING, AST_TEST_NOT_RUN, CHANNEL_TECH_NAME, ast_cdr::clid, config, CREATE_ALICE_CHANNEL, EMULATE_APP_DATA, HANGUP_CHANNEL, NULL, RAII_VAR, result, safe_channel_release(), SET_FORMATS, ast_cdr::start, SWAP_CONFIG, TEST_CATEGORY, TEST_EXECUTE, TEST_INIT, unanswered_cdr_config, and verify_mock_cdr_record().

◆ AST_TEST_DEFINE() [12/24]

AST_TEST_DEFINE ( test_cdr_fields  )

Definition at line 2120 of file test_cdr.c.

2121{
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;
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
2192
2193 CREATE_ALICE_CHANNEL(chan, &caller, &original);
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. */
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);
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);
2250 ast_test_validate(test, strcmp(varbuffer, "\"Alice\" <100>") == 0);
2252 ast_test_validate(test, strcmp(varbuffer, "100") == 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);
2259 ast_test_validate(test, ast_cdr_getvar(ast_channel_name(chan), "dstchannel", varbuffer, sizeof(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);
2266 sscanf(varbuffer, "%lf", &db_buffer);
2268 ast_test_validate(test, ast_cdr_getvar(ast_channel_name(chan), "answer", varbuffer, sizeof(varbuffer)) == 0);
2269 sscanf(varbuffer, "%lf", &db_buffer);
2272 sscanf(varbuffer, "%lf", &db_buffer);
2274 ast_test_validate(test, ast_cdr_getvar(ast_channel_name(chan), "duration", varbuffer, sizeof(varbuffer)) == 0);
2275 sscanf(varbuffer, "%lf", &db_buffer);
2277 ast_test_validate(test, ast_cdr_getvar(ast_channel_name(chan), "billsec", varbuffer, sizeof(varbuffer)) == 0);
2278 sscanf(varbuffer, "%lf", &db_buffer);
2280 ast_test_validate(test, ast_cdr_getvar(ast_channel_name(chan), "disposition", varbuffer, sizeof(varbuffer)) == 0);
2281 sscanf(varbuffer, "%d", &int_buffer);
2283 ast_test_validate(test, ast_cdr_getvar(ast_channel_name(chan), "uniqueid", varbuffer, sizeof(varbuffer)) == 0);
2285 ast_test_validate(test, ast_cdr_getvar(ast_channel_name(chan), "linkedid", varbuffer, sizeof(varbuffer)) == 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. */
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 */
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);
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}
void ast_cdr_setuserfield(const char *channel_name, const char *userfield)
Set CDR user field for channel (stored in CDR)
Definition cdr.c:3625
int ast_cdr_setvar(const char *channel_name, const char *name, const char *value)
Set a variable on a CDR.
Definition cdr.c:3316
@ AST_CDR_NULL
Definition cdr.h:259
@ AST_CDR_FLAG_FINALIZE
Definition cdr.h:248
@ AST_CDR_FLAG_KEEP_VARS
Definition cdr.h:244
int ast_cdr_fork(const char *channel_name, struct ast_flags *options)
Fork a CDR.
Definition cdr.c:3785
int ast_cdr_getvar(const char *channel_name, const char *name, char *value, size_t length)
Retrieve a CDR variable from a channel's current CDR.
Definition cdr.c:3470
const char * ast_channel_name(const struct ast_channel *chan)
void ast_channel_appl_set(struct ast_channel *chan, const char *value)
void ast_hangup(struct ast_channel *chan)
Hang up a channel.
Definition channel.c:2513
#define ast_channel_lock(chan)
Definition channel.h:2982
void ast_channel_data_set(struct ast_channel *chan, const char *value)
@ AST_AMA_OMIT
Definition channel.h:1199
void ast_channel_amaflags_set(struct ast_channel *chan, enum ama_flags value)
void ast_channel_priority_set(struct ast_channel *chan, int value)
void ast_channel_hangupcause_set(struct ast_channel *chan, int value)
int ast_setstate(struct ast_channel *chan, enum ast_channel_state)
Change the state of a channel.
Definition channel.c:7373
void ast_channel_publish_snapshot(struct ast_channel *chan)
Publish a ast_channel_snapshot for a channel.
Structure used to handle boolean flags.
Definition utils.h:217
#define EPSILON
Definition test_cdr.c:49

References ALICE_CALLERID, ao2_alloc, ao2_cleanup, AST_AMA_OMIT, AST_CAUSE_NORMAL, AST_CDR_ANSWERED, AST_CDR_FAILED, AST_CDR_FLAG_FINALIZE, AST_CDR_FLAG_KEEP_VARS, ast_cdr_fork(), ast_cdr_getvar(), AST_CDR_NULL, ast_cdr_setuserfield(), ast_cdr_setvar(), ast_channel_amaflags_set(), ast_channel_appl_set(), ast_channel_data_set(), ast_channel_hangupcause_set(), ast_channel_linkedid(), ast_channel_lock, ast_channel_name(), ast_channel_priority_set(), ast_channel_publish_snapshot(), ast_channel_uniqueid(), ast_channel_unlock, ast_copy_string(), ast_hangup(), ast_set_flag, ast_setstate(), AST_STATE_UP, AST_TEST_NOT_RUN, CHANNEL_TECH_NAME, ast_cdr::clid, config, CREATE_ALICE_CHANNEL, do_sleep(), EPSILON, ast_cdr::next, NULL, RAII_VAR, result, safe_channel_release(), ast_cdr::start, SWAP_CONFIG, TEST_CATEGORY, TEST_EXECUTE, TEST_INIT, to_sleep, unanswered_cdr_config, and verify_mock_cdr_record().

◆ AST_TEST_DEFINE() [13/24]

AST_TEST_DEFINE ( test_cdr_fork_cdr  )

Definition at line 2394 of file test_cdr.c.

2395{
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;
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
2457
2458 CREATE_ALICE_CHANNEL(chan, &caller, &original);
2463
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
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 */
2479
2480 /* Test keep variables; setting a new answer time */
2481 ast_channel_lock(chan);
2483 ast_channel_unlock(chan);
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);
2489 ast_test_validate(test, ast_cdr_getvar(ast_channel_name(chan), "start", start_time, sizeof(start_time)) == 0);
2490
2497 ast_test_validate(test, ast_cdr_getvar(ast_channel_name(chan), "test_variable", fork_varbuffer, sizeof(fork_varbuffer)) == 0);
2499 ast_test_validate(test, strcmp(fork_start_time, start_time) == 0);
2501
2507 ast_test_validate(test, strcmp(fork_start_time, start_time) != 0);
2509
2511 ast_hangup(chan);
2512 chan = NULL;
2513 result = verify_mock_cdr_record(test, expected, 3);
2514
2515 return result;
2516}
@ AST_CDR_FLAG_RESET
Definition cdr.h:250
@ AST_CDR_FLAG_SET_ANSWER
Definition cdr.h:249

References ALICE_CALLERID, ao2_alloc, ao2_cleanup, AST_AMA_DOCUMENTATION, AST_CAUSE_NORMAL, AST_CDR_ANSWERED, AST_CDR_FLAG_FINALIZE, AST_CDR_FLAG_KEEP_VARS, AST_CDR_FLAG_RESET, AST_CDR_FLAG_SET_ANSWER, ast_cdr_fork(), ast_cdr_getvar(), ast_cdr_setvar(), ast_channel_hangupcause_set(), ast_channel_linkedid(), ast_channel_lock, ast_channel_name(), ast_channel_uniqueid(), ast_channel_unlock, ast_clear_flag, ast_copy_string(), ast_hangup(), ast_set_flag, ast_setstate(), AST_STATE_UP, AST_TEST_NOT_RUN, CHANNEL_TECH_NAME, ast_cdr::clid, config, CREATE_ALICE_CHANNEL, debug_cdr_config, do_sleep(), ast_cdr::next, NULL, RAII_VAR, result, safe_channel_release(), ast_cdr::start, SWAP_CONFIG, TEST_CATEGORY, TEST_EXECUTE, TEST_INIT, to_sleep, and verify_mock_cdr_record().

◆ AST_TEST_DEFINE() [14/24]

AST_TEST_DEFINE ( test_cdr_no_reset_cdr  )

Definition at line 2324 of file test_cdr.c.

2325{
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
2359
2360 CREATE_ALICE_CHANNEL(chan, &caller, &expected);
2361
2363
2364 /* Disable the CDR */
2366
2367 /* Fork the CDR. This should be enabled */
2370
2371 /* Disable and enable the forked CDR */
2374
2375 /* Fork and finalize again. This CDR should be propagated */
2377
2378 /* Disable all future CDRs */
2380
2381 /* Fork a few more */
2385
2387 ast_hangup(chan);
2388 chan = NULL;
2389 result = verify_mock_cdr_record(test, &expected, 1);
2390
2391 return result;
2392}
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:3723
@ AST_CDR_FLAG_DISABLE_ALL
Definition cdr.h:246
@ AST_CDR_FLAG_DISABLE
Definition cdr.h:245
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:3696

References ALICE_CALLERID, ao2_alloc, ao2_cleanup, AST_AMA_DOCUMENTATION, AST_CAUSE_NORMAL, ast_cdr_clear_property(), AST_CDR_FAILED, AST_CDR_FLAG_DISABLE, AST_CDR_FLAG_DISABLE_ALL, AST_CDR_FLAG_FINALIZE, ast_cdr_fork(), ast_cdr_set_property(), ast_channel_hangupcause_set(), ast_channel_name(), ast_hangup(), ast_set_flag, AST_TEST_NOT_RUN, CHANNEL_TECH_NAME, ast_cdr::clid, config, CREATE_ALICE_CHANNEL, do_sleep(), NULL, RAII_VAR, result, safe_channel_release(), ast_cdr::start, SWAP_CONFIG, TEST_CATEGORY, TEST_EXECUTE, TEST_INIT, to_sleep, unanswered_cdr_config, and verify_mock_cdr_record().

◆ AST_TEST_DEFINE() [15/24]

AST_TEST_DEFINE ( test_cdr_outbound_bridged_call  )

Definition at line 535 of file test_cdr.c.

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),
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
591
594
595 bridge = ast_bridge_basic_new();
596 ast_test_validate(test, bridge != NULL);
598
600
608 EMULATE_APP_DATA(chan_bob, 0, "AppDial", "(Outgoing Line)");
609
613
615
617
619
621
624
627
629 return result;
630}
@ AST_FLAG_ORIGINATED
Definition channel.h:1059

References ALICE_CALLERID, ao2_alloc, ao2_cleanup, AST_AMA_DOCUMENTATION, ast_bridge_basic_new(), ast_bridge_depart(), ast_bridge_impart(), AST_BRIDGE_IMPART_CHAN_DEPARTABLE, AST_CAUSE_NORMAL, AST_CDR_ANSWERED, ast_channel_alloc, ast_channel_flags(), ast_channel_linkedid(), ast_channel_publish_dial(), ast_channel_state_set(), ast_channel_uniqueid(), ast_channel_unlock, ast_copy_string(), AST_FLAG_ORIGINATED, AST_FLAG_OUTGOING, ast_set_flag, AST_STATE_DOWN, AST_STATE_RINGING, AST_STATE_UP, AST_TEST_NOT_RUN, CHANNEL_TECH_NAME, ast_cdr::clid, config, CREATE_ALICE_CHANNEL, debug_cdr_config, do_sleep(), EMULATE_APP_DATA, HANGUP_CHANNEL, NULL, RAII_VAR, result, safe_bridge_destroy(), safe_channel_release(), SET_FORMATS, ast_cdr::start, SWAP_CONFIG, TEST_CATEGORY, TEST_EXECUTE, TEST_INIT, to_sleep, and verify_mock_cdr_record().

◆ AST_TEST_DEFINE() [16/24]

AST_TEST_DEFINE ( test_cdr_park  )

Definition at line 2030 of file test_cdr.c.

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 }
2085
2087 EMULATE_APP_DATA(chan_alice, 1, "Park", "700");
2090
2092 EMULATE_APP_DATA(chan_bob, 1, "Park", "701");
2095
2099 "test_cdr", "test_cdr_park", NULL);
2100 ast_test_validate(test, bridge != NULL);
2101
2109
2110 /* And then it hangs up */
2113
2115
2116 return result;
2117}
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:999
@ AST_BRIDGE_CAPABILITY_HOLDING
Definition bridge.h:90
@ AST_BRIDGE_FLAG_SWAP_INHIBIT_FROM
@ AST_BRIDGE_FLAG_TRANSFER_PROHIBITED
@ AST_BRIDGE_FLAG_MERGE_INHIBIT_TO
@ AST_BRIDGE_FLAG_MERGE_INHIBIT_FROM
#define CREATE_BOB_CHANNEL(channel_var, caller_id, expected_record)
Create a test_cdr_chan_tech for Bob, and set the expected CDR records' linkedid and uniqueid.
Definition test_cdr.c:259
#define BOB_CALLERID
Bob's Caller ID.
Definition test_cdr.c:219

References ALICE_CALLERID, ao2_alloc, ao2_cleanup, AST_AMA_DOCUMENTATION, ast_bridge_base_new(), AST_BRIDGE_CAPABILITY_HOLDING, ast_bridge_depart(), AST_BRIDGE_FLAG_MERGE_INHIBIT_FROM, AST_BRIDGE_FLAG_MERGE_INHIBIT_TO, AST_BRIDGE_FLAG_SWAP_INHIBIT_FROM, AST_BRIDGE_FLAG_TRANSFER_PROHIBITED, ast_bridge_impart(), AST_BRIDGE_IMPART_CHAN_DEPARTABLE, AST_CAUSE_NORMAL, AST_CDR_ANSWERED, ast_channel_lock, ast_channel_unlock, ast_setstate(), AST_STATE_UP, AST_TEST_NOT_RUN, BOB_CALLERID, CHANNEL_TECH_NAME, ast_cdr::clid, config, CREATE_ALICE_CHANNEL, CREATE_BOB_CHANNEL, debug_cdr_config, do_sleep(), EMULATE_APP_DATA, HANGUP_CHANNEL, NULL, RAII_VAR, result, safe_bridge_destroy(), safe_channel_release(), ast_cdr::start, SWAP_CONFIG, TEST_CATEGORY, TEST_EXECUTE, TEST_INIT, to_sleep, and verify_mock_cdr_record().

◆ AST_TEST_DEFINE() [17/24]

AST_TEST_DEFINE ( test_cdr_single_bridge  )

Definition at line 684 of file test_cdr.c.

685{
687 RAII_VAR(struct ast_bridge *, bridge, NULL, safe_bridge_destroy);
688 RAII_VAR(struct ast_cdr_config *, config, ao2_alloc(sizeof(*config), NULL),
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 }
720 CREATE_ALICE_CHANNEL(chan, &caller, &expected);
721
722 ast_channel_lock(chan);
723 EMULATE_APP_DATA(chan, 1, "Answer", "");
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
733
735
736 ast_bridge_depart(chan);
737
739
740 result = verify_mock_cdr_record(test, &expected, 1);
741
742 return result;
743}

References ALICE_CALLERID, ao2_alloc, ao2_cleanup, AST_AMA_DOCUMENTATION, ast_bridge_basic_new(), ast_bridge_depart(), ast_bridge_impart(), AST_BRIDGE_IMPART_CHAN_DEPARTABLE, AST_CAUSE_NORMAL, AST_CDR_ANSWERED, ast_channel_lock, ast_channel_unlock, ast_setstate(), AST_STATE_UP, AST_TEST_NOT_RUN, CHANNEL_TECH_NAME, ast_cdr::clid, config, CREATE_ALICE_CHANNEL, debug_cdr_config, do_sleep(), EMULATE_APP_DATA, HANGUP_CHANNEL, NULL, RAII_VAR, result, safe_bridge_destroy(), safe_channel_release(), ast_cdr::start, SWAP_CONFIG, TEST_CATEGORY, TEST_EXECUTE, TEST_INIT, to_sleep, and verify_mock_cdr_record().

◆ AST_TEST_DEFINE() [18/24]

AST_TEST_DEFINE ( test_cdr_single_bridge_continue  )

Definition at line 745 of file test_cdr.c.

746{
748 RAII_VAR(struct ast_bridge *, bridge, NULL, safe_bridge_destroy);
749 RAII_VAR(struct ast_cdr_config *, config, ao2_alloc(sizeof(*config), NULL),
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 }
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", "");
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);
807
809
811
812 ast_bridge_depart(chan);
813
814 EMULATE_APP_DATA(chan, 3, "Wait", "");
815
816 /* And then it hangs up */
818
820
821 return result;
822}

References ALICE_CALLERID, ao2_alloc, ao2_cleanup, AST_AMA_DOCUMENTATION, ast_bridge_basic_new(), ast_bridge_depart(), ast_bridge_impart(), AST_BRIDGE_IMPART_CHAN_DEPARTABLE, AST_CAUSE_NORMAL, AST_CDR_ANSWERED, ast_channel_lock, ast_channel_unlock, ast_setstate(), AST_STATE_UP, AST_TEST_NOT_RUN, CHANNEL_TECH_NAME, ast_cdr::clid, config, COPY_IDS, CREATE_ALICE_CHANNEL, debug_cdr_config, do_sleep(), EMULATE_APP_DATA, HANGUP_CHANNEL, NULL, RAII_VAR, result, safe_bridge_destroy(), safe_channel_release(), ast_cdr::start, SWAP_CONFIG, TEST_CATEGORY, TEST_EXECUTE, TEST_INIT, to_sleep, and verify_mock_cdr_record().

◆ AST_TEST_DEFINE() [19/24]

AST_TEST_DEFINE ( test_cdr_single_multiparty_bridge  )

Definition at line 1009 of file test_cdr.c.

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 }
1102
1104 EMULATE_APP_DATA(chan_alice, 1, "Answer", "");
1106 EMULATE_APP_DATA(chan_alice, 2, "Bridge", "");
1108
1109 bridge = ast_bridge_basic_new();
1110 ast_test_validate(test, bridge != NULL);
1112
1114
1116 EMULATE_APP_DATA(chan_bob, 1, "Answer", "");
1118 EMULATE_APP_DATA(chan_bob, 2, "Bridge", "");
1121
1123
1125
1127 EMULATE_APP_DATA(chan_charlie, 1, "Answer", "");
1129 EMULATE_APP_DATA(chan_charlie, 2, "Bridge", "");
1132
1134
1138
1142
1144
1145 return result;
1146}

References ALICE_CALLERID, ao2_alloc, ao2_cleanup, AST_AMA_DOCUMENTATION, ast_bridge_basic_new(), ast_bridge_depart(), ast_bridge_impart(), AST_BRIDGE_IMPART_CHAN_DEPARTABLE, AST_CAUSE_NORMAL, AST_CDR_ANSWERED, ast_channel_linkedid(), ast_channel_lock, ast_channel_unlock, ast_copy_string(), ast_setstate(), AST_STATE_UP, AST_TEST_NOT_RUN, BOB_CALLERID, CHANNEL_TECH_NAME, CHARLIE_CALLERID, ast_cdr::clid, config, COPY_IDS, CREATE_ALICE_CHANNEL, CREATE_BOB_CHANNEL, CREATE_CHARLIE_CHANNEL, debug_cdr_config, do_sleep(), EMULATE_APP_DATA, HANGUP_CHANNEL, NULL, RAII_VAR, result, safe_bridge_destroy(), safe_channel_release(), ast_cdr::start, SWAP_CONFIG, TEST_CATEGORY, TEST_EXECUTE, TEST_INIT, to_sleep, and verify_mock_cdr_record().

◆ AST_TEST_DEFINE() [20/24]

AST_TEST_DEFINE ( test_cdr_single_party  )

Definition at line 633 of file test_cdr.c.

634{
636 RAII_VAR(struct ast_cdr_config *, config, ao2_alloc(sizeof(*config), NULL),
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 }
669 CREATE_ALICE_CHANNEL(chan, &caller, &expected);
670
671 ast_channel_lock(chan);
672 EMULATE_APP_DATA(chan, 1, "Answer", "");
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}

References ALICE_CALLERID, ao2_alloc, ao2_cleanup, AST_AMA_DOCUMENTATION, AST_CAUSE_NORMAL, AST_CDR_ANSWERED, ast_channel_lock, ast_channel_unlock, ast_setstate(), AST_STATE_UP, AST_TEST_NOT_RUN, CHANNEL_TECH_NAME, ast_cdr::clid, config, CREATE_ALICE_CHANNEL, debug_cdr_config, EMULATE_APP_DATA, HANGUP_CHANNEL, NULL, RAII_VAR, result, safe_channel_release(), ast_cdr::start, SWAP_CONFIG, TEST_CATEGORY, TEST_EXECUTE, TEST_INIT, and verify_mock_cdr_record().

◆ AST_TEST_DEFINE() [21/24]

AST_TEST_DEFINE ( test_cdr_single_twoparty_bridge_a  )

Definition at line 824 of file test_cdr.c.

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),
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 }
880
883
885 EMULATE_APP_DATA(chan_alice, 1, "Answer", "");
887 EMULATE_APP_DATA(chan_alice, 2, "Bridge", "");
889
890 bridge = ast_bridge_basic_new();
891 ast_test_validate(test, bridge != NULL);
892
895
897 EMULATE_APP_DATA(chan_bob, 1, "Answer", "");
899 EMULATE_APP_DATA(chan_bob, 2, "Bridge", "");
901
904
907
910
912
913 return result;
914}

References ALICE_CALLERID, ao2_alloc, ao2_cleanup, AST_AMA_DOCUMENTATION, ast_bridge_basic_new(), ast_bridge_depart(), ast_bridge_impart(), AST_BRIDGE_IMPART_CHAN_DEPARTABLE, AST_CAUSE_NORMAL, AST_CDR_ANSWERED, ast_channel_linkedid(), ast_channel_lock, ast_channel_unlock, ast_copy_string(), ast_setstate(), AST_STATE_UP, AST_TEST_NOT_RUN, BOB_CALLERID, CHANNEL_TECH_NAME, ast_cdr::clid, config, CREATE_ALICE_CHANNEL, CREATE_BOB_CHANNEL, debug_cdr_config, do_sleep(), EMULATE_APP_DATA, HANGUP_CHANNEL, NULL, RAII_VAR, result, safe_bridge_destroy(), safe_channel_release(), ast_cdr::start, SWAP_CONFIG, TEST_CATEGORY, TEST_EXECUTE, TEST_INIT, to_sleep, and verify_mock_cdr_record().

◆ AST_TEST_DEFINE() [22/24]

AST_TEST_DEFINE ( test_cdr_single_twoparty_bridge_b  )

Definition at line 916 of file test_cdr.c.

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),
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 }
972
975
977 EMULATE_APP_DATA(chan_alice, 1, "Answer", "");
979 EMULATE_APP_DATA(chan_alice, 2, "Bridge", "");
981
982 bridge = ast_bridge_basic_new();
983 ast_test_validate(test, bridge != NULL);
984
986 EMULATE_APP_DATA(chan_bob, 1, "Answer", "");
988 EMULATE_APP_DATA(chan_bob, 2, "Bridge", "");
991
994
997
1000
1003
1005
1006 return result;
1007}

References ALICE_CALLERID, ao2_alloc, ao2_cleanup, AST_AMA_DOCUMENTATION, ast_bridge_basic_new(), ast_bridge_depart(), ast_bridge_impart(), AST_BRIDGE_IMPART_CHAN_DEPARTABLE, AST_CAUSE_NORMAL, AST_CDR_ANSWERED, ast_channel_linkedid(), ast_channel_lock, ast_channel_unlock, ast_copy_string(), ast_setstate(), AST_STATE_UP, AST_TEST_NOT_RUN, BOB_CALLERID, CHANNEL_TECH_NAME, ast_cdr::clid, config, CREATE_ALICE_CHANNEL, CREATE_BOB_CHANNEL, debug_cdr_config, do_sleep(), EMULATE_APP_DATA, HANGUP_CHANNEL, NULL, RAII_VAR, result, safe_bridge_destroy(), safe_channel_release(), ast_cdr::start, SWAP_CONFIG, TEST_CATEGORY, TEST_EXECUTE, TEST_INIT, to_sleep, and verify_mock_cdr_record().

◆ AST_TEST_DEFINE() [23/24]

AST_TEST_DEFINE ( test_cdr_unanswered_inbound_call  )

Definition at line 435 of file test_cdr.c.

436{
438 RAII_VAR(struct ast_cdr_config *, config, ao2_alloc(sizeof(*config), NULL),
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
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}

References ALICE_CALLERID, ao2_alloc, ao2_cleanup, AST_AMA_DOCUMENTATION, AST_CAUSE_NORMAL, AST_CDR_NOANSWER, AST_TEST_NOT_RUN, CHANNEL_TECH_NAME, ast_cdr::clid, config, CREATE_ALICE_CHANNEL, EMULATE_APP_DATA, HANGUP_CHANNEL, NULL, RAII_VAR, result, safe_channel_release(), ast_cdr::start, SWAP_CONFIG, TEST_CATEGORY, TEST_EXECUTE, TEST_INIT, unanswered_cdr_config, and verify_mock_cdr_record().

◆ AST_TEST_DEFINE() [24/24]

AST_TEST_DEFINE ( test_cdr_unanswered_outbound_call  )

Definition at line 483 of file test_cdr.c.

484{
486 RAII_VAR(struct ast_cdr_config *, config, ao2_alloc(sizeof(*config), NULL),
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
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}
void ast_channel_exten_set(struct ast_channel *chan, const char *value)
void ast_channel_context_set(struct ast_channel *chan, const char *value)
struct ast_party_id id
Caller party ID.
Definition channel.h:422
struct ast_party_name name
Subscriber name.
Definition channel.h:342
char * str
Subscriber name (Malloced)
Definition channel.h:266

References ao2_alloc, ao2_cleanup, AST_AMA_DOCUMENTATION, AST_CAUSE_NORMAL, AST_CDR_NOANSWER, ast_channel_context_set(), ast_channel_exten_set(), ast_channel_flags(), AST_FLAG_ORIGINATED, ast_set_flag, AST_TEST_NOT_RUN, CHANNEL_TECH_NAME, ast_cdr::clid, config, CREATE_ALICE_CHANNEL, EMULATE_APP_DATA, HANGUP_CHANNEL, ast_party_caller::id, ast_party_id::name, NULL, RAII_VAR, result, safe_channel_release(), ast_cdr::start, ast_party_name::str, SWAP_CONFIG, TEST_CATEGORY, TEST_EXECUTE, TEST_INIT, unanswered_cdr_config, and verify_mock_cdr_record().

◆ clear_mock_cdr_backend()

static void clear_mock_cdr_backend ( void  )
static

Definition at line 169 of file test_cdr.c.

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}
#define ast_free(a)
Definition astmm.h:180
void ast_cdr_free(struct ast_cdr *cdr)
Free a CDR record.
Definition cdr.c:3557
#define AST_LIST_LOCK(head)
Locks a list.
Definition linkedlists.h:40
#define AST_LIST_REMOVE_HEAD(head, field)
Removes and returns the head entry from a list.
#define AST_LIST_UNLOCK(head)
Attempts to unlock a list.
Definition test_cdr.c:96
struct ast_cdr * cdr
Definition test_cdr.c:97
struct test_cdr_entry::@531 list
static int global_mock_cdr_count
The number of CDRs the mock backend has received.
Definition test_cdr.c:102
static struct @530 actual_cdr_entries
A linked list of received CDR entries from the engine.

References actual_cdr_entries, ast_cdr_free(), ast_free, AST_LIST_LOCK, AST_LIST_REMOVE_HEAD, AST_LIST_UNLOCK, test_cdr_entry::cdr, global_mock_cdr_count, and test_cdr_entry::list.

Referenced by test_cdr_cleanup_cb(), test_cdr_init_cb(), and unload_module().

◆ do_sleep()

static void do_sleep ( struct timespec *  to_sleep)
static

Definition at line 387 of file test_cdr.c.

388{
389 while ((nanosleep(to_sleep, to_sleep) == -1) && (errno == EINTR)) {
390 }
391}
int errno

References errno, and to_sleep.

◆ load_module()

static int load_module ( void  )
static

Definition at line 2585 of file test_cdr.c.

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
2619 ast_test_register_init(TEST_CATEGORY, test_cdr_init_cb);
2620 ast_test_register_cleanup(TEST_CATEGORY, test_cdr_cleanup_cb);
2621
2624
2626}
int ast_cdr_register(const char *name, const char *desc, ast_cdrbe be)
Register a CDR handling engine.
Definition cdr.c:3076
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
#define ast_cond_init(cond, attr)
Definition lock.h:208
@ AST_MODULE_LOAD_SUCCESS
Definition module.h:70
#define AST_TEST_REGISTER(cb)
Definition test.h:127
static int test_cdr_cleanup_cb(struct ast_test_info *info, struct ast_test *test)
Definition test_cdr.c:2534
static ast_cond_t mock_cdr_cond
The Mock CDR backend condition wait.
Definition test_cdr.c:88
static int mock_cdr_backend_cb(struct ast_cdr *cdr)
Definition test_cdr.c:116
static int test_cdr_init_cb(struct ast_test_info *info, struct ast_test *test)
Definition test_cdr.c:2522
static struct ast_channel_tech test_cdr_chan_tech
A channel technology used for the unit tests.
Definition test_cdr.c:91
#define MOCK_CDR_BACKEND
Definition test_cdr.c:53

References ast_cdr_register(), ast_channel_register(), ast_cond_init, AST_MODULE_LOAD_SUCCESS, AST_TEST_REGISTER, MOCK_CDR_BACKEND, mock_cdr_backend_cb(), mock_cdr_cond, NULL, ast_cdr::start, TEST_CATEGORY, test_cdr_chan_tech, test_cdr_cleanup_cb(), and test_cdr_init_cb().

◆ mock_cdr_backend_cb()

static int mock_cdr_backend_cb ( struct ast_cdr cdr)
static

Definition at line 116 of file test_cdr.c.

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
158 AST_LIST_INSERT_TAIL(&actual_cdr_entries, cdr_wrapper, list);
162
163 return 0;
164}
#define ast_calloc(num, len)
A wrapper for calloc()
Definition astmm.h:202
#define ast_var_assign(name, value)
Definition chanvars.h:40
#define AST_LIST_TRAVERSE(head, var, field)
Loops over (traverses) the entries in a list.
#define AST_LIST_INSERT_TAIL(head, elm, field)
Appends a list entry to the tail of a list.
#define ast_cond_signal(cond)
Definition lock.h:210
struct varshead varshead
Definition cdr.h:332
char name[0]
Definition chanvars.h:31
struct ast_var_t::@224 entries
char * value
Definition chanvars.h:30
struct ast_var_t * last
Definition chanvars.h:34
struct ast_var_t * first
Definition chanvars.h:34

References actual_cdr_entries, ast_calloc, ast_cond_signal, AST_LIST_INSERT_TAIL, AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_var_assign, test_cdr_entry::cdr, ast_var_t::entries, varshead::first, global_mock_cdr_count, varshead::last, mock_cdr_cond, ast_var_t::name, ast_cdr::next, NULL, ast_cdr::start, ast_var_t::value, and ast_cdr::varshead.

Referenced by load_module().

◆ safe_bridge_destroy()

static void safe_bridge_destroy ( struct ast_bridge bridge)
static

Definition at line 379 of file test_cdr.c.

380{
381 if (!bridge) {
382 return;
383 }
384 ast_bridge_destroy(bridge, 0);
385}
int ast_bridge_destroy(struct ast_bridge *bridge, int cause)
Destroy a bridge.
Definition bridge.c:1009

References ast_bridge_destroy().

Referenced by AST_TEST_DEFINE(), AST_TEST_DEFINE(), AST_TEST_DEFINE(), AST_TEST_DEFINE(), AST_TEST_DEFINE(), AST_TEST_DEFINE(), AST_TEST_DEFINE(), AST_TEST_DEFINE(), AST_TEST_DEFINE(), and AST_TEST_DEFINE().

◆ safe_channel_release()

static void safe_channel_release ( struct ast_channel chan)
static

◆ test_cdr_cleanup_cb()

static int test_cdr_cleanup_cb ( struct ast_test_info info,
struct ast_test *  test 
)
static

Definition at line 2534 of file test_cdr.c.

2535{
2536 /* Restore the real config */
2541
2542 return 0;
2543}
void ast_cdr_set_config(struct ast_cdr_config *config)
Set the current CDR configuration.
Definition cdr.c:2973
static void clear_mock_cdr_backend(void)
Definition test_cdr.c:169
static struct ast_cdr_config * saved_config
A placeholder for Asterisk's 'real' CDR configuration.
Definition test_cdr.c:58

References ao2_cleanup, ast_cdr_set_config(), clear_mock_cdr_backend(), NULL, and saved_config.

Referenced by load_module().

◆ test_cdr_init_cb()

static int test_cdr_init_cb ( struct ast_test_info info,
struct ast_test *  test 
)
static

Definition at line 2522 of file test_cdr.c.

2523{
2524 /* Back up the real config */
2527 return 0;
2528}
struct ast_cdr_config * ast_cdr_get_config(void)
Obtain the current CDR configuration.
Definition cdr.c:2959

References ast_cdr_get_config(), clear_mock_cdr_backend(), and saved_config.

Referenced by load_module().

◆ unload_module()

static int unload_module ( void  )
static

Definition at line 2546 of file test_cdr.c.

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
2581
2582 return 0;
2583}
int ast_cdr_unregister(const char *name)
Unregister a CDR handling engine.
Definition cdr.c:3121
void ast_channel_unregister(const struct ast_channel_tech *tech)
Unregister a channel technology.
Definition channel.c:570
#define AST_TEST_UNREGISTER(cb)
Definition test.h:128

References ast_cdr_unregister(), ast_channel_unregister(), AST_TEST_UNREGISTER, clear_mock_cdr_backend(), MOCK_CDR_BACKEND, ast_cdr::start, and test_cdr_chan_tech.

◆ verify_mock_cdr_record()

static enum ast_test_result_state verify_mock_cdr_record ( struct ast_test *  test,
struct ast_cdr expected,
int  record 
)
static

Definition at line 310 of file test_cdr.c.

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 }
324 cdr_wrapper = AST_LIST_REMOVE_HEAD(&actual_cdr_entries, list);
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}
static int amaflags
Definition chan_iax2.c:500
static char accountcode[AST_MAX_ACCOUNT_CODE]
Definition chan_iax2.c:497
static int answer(void *data)
Definition chan_pjsip.c:687
char * end
Definition eagi_proxy.c:73
#define ast_cond_timedwait(cond, mutex, time)
Definition lock.h:213
#define S_OR(a, b)
returns the equivalent of logic or for strings: first one if not empty, otherwise second one.
Definition strings.h:80
char dstchannel[AST_MAX_EXTENSION]
Definition cdr.h:293
long int billsec
Definition cdr.h:307
char channel[AST_MAX_EXTENSION]
Definition cdr.h:291
#define ast_test_debug(test, fmt,...)
Definition test.h:130
#define ast_test_status_update(a, b, c...)
Definition test.h:129
@ AST_TEST_PASS
Definition test.h:195
#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 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
struct timeval ast_tvnow(void)
Returns current timeval. Meant to replace calls to gettimeofday().
Definition time.h:159

References accountcode, actual_cdr_entries, amaflags, answer(), ast_cond_timedwait, AST_LIST_LOCK, AST_LIST_REMOVE_HEAD, AST_LIST_UNLOCK, ast_test_debug, AST_TEST_FAIL, AST_TEST_PASS, ast_test_status_update, ast_tvnow(), ast_cdr::billsec, test_cdr_entry::cdr, ast_cdr::channel, ast_cdr::dstchannel, end, global_mock_cdr_count, mock_cdr_cond, ast_cdr::next, NULL, S_OR, VERIFY_NUMERIC_FIELD, VERIFY_STRING_FIELD, and VERIFY_TIME_VALUE.

Referenced by AST_TEST_DEFINE(), AST_TEST_DEFINE(), AST_TEST_DEFINE(), AST_TEST_DEFINE(), AST_TEST_DEFINE(), AST_TEST_DEFINE(), AST_TEST_DEFINE(), AST_TEST_DEFINE(), AST_TEST_DEFINE(), AST_TEST_DEFINE(), AST_TEST_DEFINE(), AST_TEST_DEFINE(), AST_TEST_DEFINE(), AST_TEST_DEFINE(), AST_TEST_DEFINE(), AST_TEST_DEFINE(), AST_TEST_DEFINE(), AST_TEST_DEFINE(), AST_TEST_DEFINE(), AST_TEST_DEFINE(), AST_TEST_DEFINE(), AST_TEST_DEFINE(), AST_TEST_DEFINE(), and AST_TEST_DEFINE().

Variable Documentation

◆ __mod_info

struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_LOAD_ORDER , .description = "CDR unit tests" , .key = ASTERISK_GPL_KEY , .buildopt_sum = AST_BUILDOPT_SUM, .load = load_module, .unload = unload_module, .load_pri = AST_MODPRI_DEFAULT, .support_level = AST_MODULE_SUPPORT_CORE, }
static

Definition at line 2628 of file test_cdr.c.

◆ [struct]

struct { ... } actual_cdr_entries

A linked list of received CDR entries from the engine.

Referenced by clear_mock_cdr_backend(), mock_cdr_backend_cb(), and verify_mock_cdr_record().

◆ ast_module_info

const struct ast_module_info* ast_module_info = &__mod_info
static

Definition at line 2628 of file test_cdr.c.

◆ congestion_cdr_config

struct ast_cdr_config congestion_cdr_config
static
Initial value:
= {
}
#define CDR_DEBUG(fmt,...)
Definition cdr.c:314
@ CDR_UNANSWERED
Definition cdr.h:222
@ CDR_ENABLED
Definition cdr.h:220
@ CDR_CHANNEL_DEFAULT_ENABLED
Definition cdr.h:227
@ CDR_CONGESTION
Definition cdr.h:223

A configuration suitable for CDRs with congestion enabled.

Definition at line 71 of file test_cdr.c.

Referenced by AST_TEST_DEFINE(), and AST_TEST_DEFINE().

◆ debug_cdr_config

struct ast_cdr_config debug_cdr_config
static

◆ first

struct test_cdr_entry* first

Definition at line 85 of file test_cdr.c.

◆ global_mock_cdr_count

int global_mock_cdr_count
static

The number of CDRs the mock backend has received.

Definition at line 102 of file test_cdr.c.

Referenced by clear_mock_cdr_backend(), mock_cdr_backend_cb(), and verify_mock_cdr_record().

◆ last

struct test_cdr_entry* last

Definition at line 85 of file test_cdr.c.

◆ lock

Definition at line 85 of file test_cdr.c.

◆ mock_cdr_cond

ast_cond_t mock_cdr_cond
static

The Mock CDR backend condition wait.

Definition at line 88 of file test_cdr.c.

Referenced by load_module(), mock_cdr_backend_cb(), and verify_mock_cdr_record().

◆ saved_config

struct ast_cdr_config* saved_config
static

A placeholder for Asterisk's 'real' CDR configuration.

Definition at line 58 of file test_cdr.c.

Referenced by test_cdr_cleanup_cb(), and test_cdr_init_cb().

◆ test_cdr_chan_tech

struct ast_channel_tech test_cdr_chan_tech
static
Initial value:
= {
.description = "Mock channel technology for CDR tests",
}

A channel technology used for the unit tests.

Definition at line 91 of file test_cdr.c.

91 {
92 .type = CHANNEL_TECH_NAME,
93 .description = "Mock channel technology for CDR tests",
94};

Referenced by load_module(), and unload_module().

◆ unanswered_cdr_config

struct ast_cdr_config unanswered_cdr_config
static
Initial value:

A configuration suitable for CDRs with unanswered records.

Definition at line 66 of file test_cdr.c.

66 {
68};

Referenced by AST_TEST_DEFINE(), AST_TEST_DEFINE(), AST_TEST_DEFINE(), AST_TEST_DEFINE(), AST_TEST_DEFINE(), AST_TEST_DEFINE(), AST_TEST_DEFINE(), AST_TEST_DEFINE(), and AST_TEST_DEFINE().