Asterisk - The Open Source Telephony Project GIT-master-67613d1
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. More...
 
#define BOB_CALLERID   { .id.name.str = "Bob", .id.name.valid = 1, .id.number.str = "200", .id.number.valid = 1, }
 Bob's Caller ID. More...
 
#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. More...
 
#define COPY_IDS(channel_var, expected_record)
 Copy the linkedid and uniqueid from a channel to an expected CDR. More...
 
#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. More...
 
#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. More...
 
#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. More...
 
#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. More...
 
#define DAVID_CALLERID   { .id.name.str = "David", .id.name.valid = 1, .id.number.str = "400", .id.number.valid = 1, }
 David's Caller ID. More...
 
#define EMULATE_APP_DATA(channel, priority, application, data)
 Emulate a channel entering into an application. More...
 
#define EPSILON   0.001
 
#define HANGUP_CHANNEL(channel, cause)
 Hang up a test channel safely. More...
 
#define MOCK_CDR_BACKEND   "mock_cdr_backend"
 
#define SET_FORMATS(chan)
 Set ulaw format on channel. More...
 
#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. More...
 
#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. More...
 
#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. More...
 
#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. More...
 

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 = "This paragraph is copyright (c) 2006 by Digium, Inc. \In order for your module to load, it must return this \key via a function called \"key\". Any code which \includes this paragraph must be licensed under the GNU \General Public License version 2 or later (at your \option). In addition to Digium's general reservations \of rights, Digium expressly reserves the right to \allow other parties to license this paragraph under \different terms. Any use of Digium, Inc. trademarks or \logos (including \"Asterisk\" or \"Digium\") without \express written permission of Digium, Inc. is prohibited.\n" , .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. More...
 
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. More...
 
static struct ast_cdr_config debug_cdr_config
 A configuration suitable for 'normal' CDRs. More...
 
static int global_mock_cdr_count
 The number of CDRs the mock backend has received. More...
 
static ast_cond_t mock_cdr_cond
 The Mock CDR backend condition wait. More...
 
static struct ast_cdr_configsaved_config
 A placeholder for Asterisk's 'real' CDR configuration. More...
 
static struct ast_channel_tech test_cdr_chan_tech
 A channel technology used for the unit tests. More...
 
static struct ast_cdr_config unanswered_cdr_config
 A configuration suitable for CDRs with unanswered records. More...
 

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.

◆ 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.

◆ 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.

◆ 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.

◆ 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.

◆ 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.

◆ 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)
#define NULL
Definition: resample.c:96

Hang up a test channel safely.

Definition at line 303 of file test_cdr.c.

◆ 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.

◆ 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.

◆ 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.

◆ 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.

◆ 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.

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:257
static PGresult * result
Definition: cel_pgsql.c:84
static const char config[]
Definition: chan_ooh323.c:111
@ AST_AMA_DOCUMENTATION
Definition: channel.h:1181
def info(msg)
The global options available for CDRs.
Definition: cdr.h:267
Responsible for call detail data.
Definition: cdr.h:279
char clid[AST_MAX_EXTENSION]
Definition: cdr.h:281
Main Channel structure associated with a channel.
Caller Party information.
Definition: channel.h:418
@ 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 CHANNEL_TECH_NAME
Definition: test_cdr.c:55
#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:941

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, sip_to_pjsip::info(), NULL, RAII_VAR, result, safe_channel_release(), 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
1964 CREATE_ALICE_CHANNEL(chan_alice, &alice_caller, &alice_expected_one);
1965 COPY_IDS(chan_alice, &alice_expected_two);
1966 COPY_IDS(chan_alice, &alice_expected_three);
1967
1968 EMULATE_APP_DATA(chan_alice, 1, "Dial", CHANNEL_TECH_NAME "/Bob");
1969
1970 chan_bob = ast_channel_alloc(0, AST_STATE_DOWN, "200", "Bob", "200", "200", "default", NULL, NULL, 0, CHANNEL_TECH_NAME "/Bob");
1971 SET_FORMATS(chan_bob);
1972 ast_channel_unlock(chan_bob);
1974 EMULATE_APP_DATA(chan_bob, 0, "AppDial", "(Outgoing Line)");
1975 ast_copy_string(bob_expected_one.uniqueid, ast_channel_uniqueid(chan_bob), sizeof(bob_expected_one.uniqueid));
1976 ast_copy_string(bob_expected_one.linkedid, ast_channel_linkedid(chan_alice), sizeof(bob_expected_one.linkedid));
1977
1978 CREATE_CHARLIE_CHANNEL(chan_charlie, &charlie_caller, &charlie_expected_one);
1979 EMULATE_APP_DATA(chan_charlie, 1, "Dial", CHANNEL_TECH_NAME "/David");
1980 ast_copy_string(charlie_expected_one.uniqueid, ast_channel_uniqueid(chan_charlie), sizeof(charlie_expected_one.uniqueid));
1981 ast_copy_string(charlie_expected_one.linkedid, ast_channel_linkedid(chan_alice), sizeof(charlie_expected_one.linkedid));
1982 ast_copy_string(charlie_expected_two.uniqueid, ast_channel_uniqueid(chan_charlie), sizeof(charlie_expected_two.uniqueid));
1983 ast_copy_string(charlie_expected_two.linkedid, ast_channel_linkedid(chan_alice), sizeof(charlie_expected_two.linkedid));
1984
1985 chan_david = ast_channel_alloc(0, AST_STATE_DOWN, "400", "David", "400", "400", "default", NULL, NULL, 0, CHANNEL_TECH_NAME "/David");
1986 SET_FORMATS(chan_david);
1987 ast_channel_unlock(chan_david);
1989 EMULATE_APP_DATA(chan_david, 0, "AppDial", "(Outgoing Line)");
1990
1991 ast_channel_publish_dial(chan_alice, chan_bob, "Bob", NULL);
1993 ast_channel_publish_dial(chan_charlie, chan_david, "David", NULL);
1995 ast_channel_publish_dial(chan_alice, chan_bob, NULL, "ANSWER");
1996 ast_channel_publish_dial(chan_charlie, chan_david, NULL, "ANSWER");
1997
2000 ast_channel_state_set(chan_charlie, AST_STATE_UP);
2002
2003 bridge = ast_bridge_basic_new();
2004 ast_test_validate(test, bridge != NULL);
2005
2007 ast_test_validate(test, !ast_bridge_impart(bridge, chan_charlie, NULL, NULL, AST_BRIDGE_IMPART_CHAN_DEPARTABLE));
2009 ast_test_validate(test, !ast_bridge_impart(bridge, chan_david, NULL, NULL, AST_BRIDGE_IMPART_CHAN_DEPARTABLE));
2011 ast_test_validate(test, !ast_bridge_impart(bridge, chan_bob, NULL, NULL, AST_BRIDGE_IMPART_CHAN_DEPARTABLE));
2013 ast_test_validate(test, !ast_bridge_impart(bridge, chan_alice, NULL, NULL, AST_BRIDGE_IMPART_CHAN_DEPARTABLE));
2015 ast_test_validate(test, !ast_bridge_depart(chan_alice));
2016 ast_test_validate(test, !ast_bridge_depart(chan_bob));
2017 ast_test_validate(test, !ast_bridge_depart(chan_charlie));
2018 ast_test_validate(test, !ast_bridge_depart(chan_david));
2019
2020 HANGUP_CHANNEL(chan_alice, AST_CAUSE_NORMAL);
2022 HANGUP_CHANNEL(chan_charlie, AST_CAUSE_NORMAL);
2023 HANGUP_CHANNEL(chan_david, AST_CAUSE_NORMAL);
2024
2025 result = verify_mock_cdr_record(test, &alice_expected_one, 6);
2026
2027 return result;
2028}
int ast_bridge_depart(struct ast_channel *chan)
Depart a channel from a bridge.
Definition: bridge.c:1906
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:1878
@ AST_BRIDGE_IMPART_CHAN_DEPARTABLE
Definition: bridge.h:588
struct ast_bridge * ast_bridge_basic_new(void)
Create a new basic class bridge.
@ AST_CDR_ANSWERED
Definition: cdr.h:261
#define ast_channel_alloc(needqueue, state, cid_num, cid_name, acctcode, exten, context, assignedids, requestor, amaflag,...)
Create a channel structure.
Definition: channel.h:1258
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:999
#define ast_channel_unlock(chan)
Definition: channel.h:2923
@ AST_STATE_RINGING
Definition: channelstate.h:41
@ AST_STATE_DOWN
Definition: channelstate.h:36
@ AST_STATE_UP
Definition: channelstate.h:42
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:349
char linkedid[AST_MAX_UNIQUEID]
Definition: cdr.h:319
char uniqueid[AST_MAX_UNIQUEID]
Definition: cdr.h:317
#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
static void do_sleep(struct timespec *to_sleep)
Definition: test_cdr.c:387
#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 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, sip_to_pjsip::info(), ast_cdr::linkedid, NULL, RAII_VAR, result, safe_bridge_destroy(), safe_channel_release(), SET_FORMATS, SWAP_CONFIG, TEST_CATEGORY, TEST_EXECUTE, TEST_INIT, to_sleep, ast_cdr::uniqueid, 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
1659 CREATE_ALICE_CHANNEL(chan_caller, &caller, &alice_expected_one);
1660 COPY_IDS(chan_caller, &alice_expected_two);
1661
1662 EMULATE_APP_DATA(chan_caller, 1, "Dial", CHANNEL_TECH_NAME "/Bob");
1663
1664 chan_callee = ast_channel_alloc(0, AST_STATE_DOWN, NULL, NULL, "200", NULL, NULL, NULL, chan_caller, 0, CHANNEL_TECH_NAME "/Bob");
1665 SET_FORMATS(chan_callee);
1666 ast_channel_unlock(chan_callee);
1668 COPY_IDS(chan_callee, &bob_expected_one);
1669
1670 ast_channel_publish_dial(chan_caller, chan_callee, "Bob", NULL);
1672 ast_channel_publish_dial(chan_caller, chan_callee, NULL, "ANSWER");
1673
1674 ast_channel_state_set(chan_caller, AST_STATE_UP);
1676 ast_channel_state_set(chan_callee, AST_STATE_UP);
1677
1678 EMULATE_APP_DATA(chan_caller, 2, "Wait", "1");
1679 EMULATE_APP_DATA(chan_callee, 1, "Wait", "1");
1680
1681 HANGUP_CHANNEL(chan_caller, AST_CAUSE_NORMAL);
1682 HANGUP_CHANNEL(chan_callee, AST_CAUSE_NORMAL);
1683
1684 result = verify_mock_cdr_record(test, &alice_expected_one, 3);
1685 return result;
1686}
#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, sip_to_pjsip::info(), NULL, RAII_VAR, result, safe_channel_release(), SET_FORMATS, 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
1731 EMULATE_APP_DATA(chan_caller, 1, "Dial", CHANNEL_TECH_NAME "/Bob");
1732
1733 chan_callee = ast_channel_alloc(0, AST_STATE_DOWN, NULL, NULL, "200", NULL, NULL, NULL, chan_caller, 0, CHANNEL_TECH_NAME "/Bob");
1734 SET_FORMATS(chan_callee);
1735 ast_channel_unlock(chan_callee);
1737 EMULATE_APP_DATA(chan_callee, 0, "AppDial", "(Outgoing Line)");
1738
1739 ast_channel_publish_dial(chan_caller, chan_callee, "Bob", NULL);
1741 ast_channel_publish_dial(chan_caller, chan_callee, NULL, "ANSWER");
1742
1743 ast_channel_state_set(chan_caller, AST_STATE_UP);
1744 ast_channel_state_set(chan_callee, AST_STATE_UP);
1745
1746 bridge = ast_bridge_basic_new();
1747 ast_test_validate(test, bridge != NULL);
1749
1750 ast_test_validate(test, !ast_bridge_impart(bridge, chan_caller, NULL, NULL, AST_BRIDGE_IMPART_CHAN_DEPARTABLE));
1751 ast_test_validate(test, !ast_bridge_impart(bridge, chan_callee, NULL, NULL, AST_BRIDGE_IMPART_CHAN_DEPARTABLE));
1752
1754
1755 ast_bridge_depart(chan_caller);
1756 ast_bridge_depart(chan_callee);
1757
1758 HANGUP_CHANNEL(chan_caller, AST_CAUSE_NORMAL);
1759 HANGUP_CHANNEL(chan_callee, AST_CAUSE_NORMAL);
1760
1761 result = verify_mock_cdr_record(test, &expected, 1);
1762 return result;
1763}

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, sip_to_pjsip::info(), NULL, RAII_VAR, result, safe_bridge_destroy(), safe_channel_release(), SET_FORMATS, 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
1808 EMULATE_APP_DATA(chan_caller, 1, "Dial", CHANNEL_TECH_NAME "/Bob");
1809
1810 chan_callee = ast_channel_alloc(0, AST_STATE_DOWN, NULL, NULL, "200", NULL, NULL, NULL, chan_caller, 0, CHANNEL_TECH_NAME "/Bob");
1811 SET_FORMATS(chan_callee);
1812 ast_channel_unlock(chan_callee);
1814 EMULATE_APP_DATA(chan_callee, 0, "AppDial", "(Outgoing Line)");
1815
1816 ast_channel_publish_dial(chan_caller, chan_callee, "Bob", NULL);
1818 ast_channel_publish_dial(chan_caller, chan_callee, NULL, "ANSWER");
1819
1820 ast_channel_state_set(chan_caller, AST_STATE_UP);
1821 ast_channel_state_set(chan_callee, AST_STATE_UP);
1822
1823 bridge = ast_bridge_basic_new();
1824 ast_test_validate(test, bridge != NULL);
1826 ast_test_validate(test, !ast_bridge_impart(bridge, chan_callee, NULL, NULL, AST_BRIDGE_IMPART_CHAN_DEPARTABLE));
1828 ast_test_validate(test, !ast_bridge_impart(bridge, chan_caller, NULL, NULL, AST_BRIDGE_IMPART_CHAN_DEPARTABLE));
1830 ast_bridge_depart(chan_caller);
1831 ast_bridge_depart(chan_callee);
1832
1833 HANGUP_CHANNEL(chan_caller, AST_CAUSE_NORMAL);
1834 HANGUP_CHANNEL(chan_callee, AST_CAUSE_NORMAL);
1835
1836 result = verify_mock_cdr_record(test, &expected, 1);
1837 return result;
1838}

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, sip_to_pjsip::info(), NULL, RAII_VAR, result, safe_bridge_destroy(), safe_channel_release(), SET_FORMATS, 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
1253 EMULATE_APP_DATA(chan_caller, 1, "Dial", CHANNEL_TECH_NAME "/Bob");
1254
1255 chan_callee = ast_channel_alloc(0, AST_STATE_DOWN, NULL, NULL, "200", NULL, NULL, NULL, chan_caller, 0, CHANNEL_TECH_NAME "/Bob");
1256 SET_FORMATS(chan_callee);
1257 ast_channel_unlock(chan_callee);
1259 EMULATE_APP_DATA(chan_callee, 0, "AppDial", "(Outgoing Line)");
1260
1261 ast_channel_publish_dial(chan_caller, chan_callee, "Bob", NULL);
1263 ast_channel_publish_dial(chan_caller, chan_callee, NULL, "BUSY");
1264
1265 HANGUP_CHANNEL(chan_caller, AST_CAUSE_BUSY);
1266 HANGUP_CHANNEL(chan_callee, AST_CAUSE_BUSY);
1267
1268 result = verify_mock_cdr_record(test, &expected, 1);
1269
1270 return result;
1271}
#define AST_CAUSE_BUSY
Definition: causes.h:149
@ AST_CDR_BUSY
Definition: cdr.h:260

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, sip_to_pjsip::info(), NULL, RAII_VAR, result, safe_channel_release(), SET_FORMATS, 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
1440 EMULATE_APP_DATA(chan_caller, 1, "Dial", CHANNEL_TECH_NAME "/Bob");
1441
1442 chan_callee = ast_channel_alloc(0, AST_STATE_DOWN, NULL, NULL, "200", NULL, NULL, NULL, chan_caller, 0, CHANNEL_TECH_NAME "/Bob");
1443 SET_FORMATS(chan_callee);
1444 ast_channel_unlock(chan_callee);
1446 EMULATE_APP_DATA(chan_callee, 0, "AppDial", "(Outgoing Line)");
1447
1448 ast_channel_publish_dial(chan_caller, chan_callee, "Bob", NULL);
1450 ast_channel_publish_dial(chan_caller, chan_callee, NULL, "CANCEL");
1451
1452 HANGUP_CHANNEL(chan_callee, AST_CAUSE_NORMAL);
1453 HANGUP_CHANNEL(chan_caller, AST_CAUSE_NORMAL);
1454
1455 result = verify_mock_cdr_record(test, &expected, 1);
1456
1457 return result;
1458}

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, sip_to_pjsip::info(), NULL, RAII_VAR, result, safe_channel_release(), SET_FORMATS, 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
1315 EMULATE_APP_DATA(chan_caller, 1, "Dial", CHANNEL_TECH_NAME "/Bob");
1316
1317 chan_callee = ast_channel_alloc(0, AST_STATE_DOWN, NULL, NULL, "200", NULL, NULL, NULL, chan_caller, 0, CHANNEL_TECH_NAME "/Bob");
1318 SET_FORMATS(chan_callee);
1319 ast_channel_unlock(chan_callee);
1321 EMULATE_APP_DATA(chan_callee, 0, "AppDial", "(Outgoing Line)");
1322
1323 ast_channel_publish_dial(chan_caller, chan_callee, "Bob", NULL);
1325 ast_channel_publish_dial(chan_caller, chan_callee, NULL, "CONGESTION");
1326
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:262
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, sip_to_pjsip::info(), NULL, RAII_VAR, result, safe_channel_release(), SET_FORMATS, 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;
1518 bob_expected.next = &charlie_expected;
1519 charlie_expected.next = &david_expected;
1520
1521 switch (cmd) {
1522 case TEST_INIT:
1523 info->name = __func__;
1524 info->category = TEST_CATEGORY;
1525 info->summary = "Test a parallel dial where all channels fail to answer";
1526 info->description =
1527 "This tests dialing three parties: Bob, Charlie, David. Charlie\n"
1528 "returns BUSY; David returns CONGESTION; Bob fails to answer and\n"
1529 "Alice hangs up. Three records are created for Alice as a result.";
1530 return AST_TEST_NOT_RUN;
1531 case TEST_EXECUTE:
1532 break;
1533 }
1534
1536
1537 CREATE_ALICE_CHANNEL(chan_caller, &caller, &bob_expected);
1538 COPY_IDS(chan_caller, &charlie_expected);
1539 COPY_IDS(chan_caller, &david_expected);
1540
1541 /* Channel enters Dial app */
1542 EMULATE_APP_DATA(chan_caller, 1, "Dial", CHANNEL_TECH_NAME "/Bob&" CHANNEL_TECH_NAME "/Charlie&" CHANNEL_TECH_NAME "/David");
1543
1544 /* Outbound channels are created */
1545 chan_bob = ast_channel_alloc(0, AST_STATE_DOWN, NULL, NULL, "200", NULL, NULL, NULL, chan_caller, 0, CHANNEL_TECH_NAME "/Bob");
1546 SET_FORMATS(chan_bob);
1547 ast_channel_unlock(chan_bob);
1549 EMULATE_APP_DATA(chan_bob, 0, "AppDial", "(Outgoing Line)");
1550
1551 chan_charlie = ast_channel_alloc(0, AST_STATE_DOWN, NULL, NULL, "300", NULL, NULL, NULL, chan_caller, 0, CHANNEL_TECH_NAME "/Charlie");
1552 SET_FORMATS(chan_charlie);
1553 ast_channel_unlock(chan_charlie);
1555 EMULATE_APP_DATA(chan_charlie, 0, "AppDial", "(Outgoing Line)");
1556
1557 chan_david = ast_channel_alloc(0, AST_STATE_DOWN, NULL, NULL, "400", NULL, NULL, NULL, chan_caller, 0, CHANNEL_TECH_NAME "/David");
1558 SET_FORMATS(chan_charlie);
1559 ast_channel_unlock(chan_david);
1561 EMULATE_APP_DATA(chan_david, 0, "AppDial", "(Outgoing Line)");
1562
1563 /* Dial starts */
1564 ast_channel_publish_dial(chan_caller, chan_bob, "Bob", NULL);
1565 ast_channel_publish_dial(chan_caller, chan_charlie, "Charlie", NULL);
1566 ast_channel_publish_dial(chan_caller, chan_david, "David", NULL);
1568
1569 /* Charlie is busy */
1570 ast_channel_publish_dial(chan_caller, chan_charlie, NULL, "BUSY");
1571 HANGUP_CHANNEL(chan_charlie, AST_CAUSE_BUSY);
1572
1573 /* David is congested */
1574 ast_channel_publish_dial(chan_caller, chan_david, NULL, "CONGESTION");
1576
1577 /* Bob is canceled */
1578 ast_channel_publish_dial(chan_caller, chan_bob, NULL, "CANCEL");
1580
1581 /* Alice hangs up */
1582 HANGUP_CHANNEL(chan_caller, AST_CAUSE_NORMAL);
1583
1584 result = verify_mock_cdr_record(test, expected, 3);
1585
1586 return result;
1587}
struct ast_cdr * next
Definition: cdr.h:328

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, sip_to_pjsip::info(), ast_cdr::next, NULL, RAII_VAR, result, safe_channel_release(), SET_FORMATS, 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
1192 chan_callee = ast_channel_alloc(0, AST_STATE_DOWN, NULL, NULL, "200", NULL, NULL, NULL, chan_caller, 0, CHANNEL_TECH_NAME "/Bob");
1193 SET_FORMATS(chan_callee);
1194 ast_channel_unlock(chan_callee);
1196 EMULATE_APP_DATA(chan_callee, 0, "AppDial", "(Outgoing Line)");
1197
1198 ast_channel_publish_dial(chan_caller, chan_callee, "Bob", NULL);
1200 ast_channel_publish_dial(chan_caller, chan_callee, NULL, "NOANSWER");
1201
1202 HANGUP_CHANNEL(chan_caller, AST_CAUSE_NO_ANSWER);
1203 HANGUP_CHANNEL(chan_callee, AST_CAUSE_NO_ANSWER);
1204
1205 result = verify_mock_cdr_record(test, &expected, 1);
1206
1207 return result;
1208}
#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, sip_to_pjsip::info(), NULL, RAII_VAR, result, safe_channel_release(), SET_FORMATS, 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
1377 EMULATE_APP_DATA(chan_caller, 1, "Dial", CHANNEL_TECH_NAME "/Bob");
1378
1379 chan_callee = ast_channel_alloc(0, AST_STATE_DOWN, NULL, NULL, "200", NULL, NULL, NULL, chan_caller, 0, CHANNEL_TECH_NAME "/Bob");
1380 SET_FORMATS(chan_callee);
1381 ast_channel_unlock(chan_callee);
1383 EMULATE_APP_DATA(chan_callee, 0, "AppDial", "(Outgoing Line)");
1384
1385 ast_channel_publish_dial(chan_caller, chan_callee, "Bob", NULL);
1387 ast_channel_publish_dial(chan_caller, chan_callee, NULL, "CHANUNAVAIL");
1388
1391
1392 result = verify_mock_cdr_record(test, &expected, 1);
1393
1394 return result;
1395}
#define AST_CAUSE_NO_ROUTE_DESTINATION
Definition: causes.h:100
@ AST_CDR_FAILED
Definition: cdr.h:259

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, sip_to_pjsip::info(), NULL, RAII_VAR, result, safe_channel_release(), SET_FORMATS, 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;
2176 original.next = &fork_expected_one;
2177 fork_expected_one.next = &fork_expected_two;
2178
2179 switch (cmd) {
2180 case TEST_INIT:
2181 info->name = __func__;
2182 info->category = TEST_CATEGORY;
2183 info->summary = "Test field access CDRs";
2184 info->description =
2185 "This tests setting/retrieving data on CDR records.";
2186 return AST_TEST_NOT_RUN;
2187 case TEST_EXECUTE:
2188 break;
2189 }
2190
2192
2193 CREATE_ALICE_CHANNEL(chan, &caller, &original);
2194 ast_copy_string(fork_expected_one.uniqueid, ast_channel_uniqueid(chan), sizeof(fork_expected_one.uniqueid));
2195 ast_copy_string(fork_expected_one.linkedid, ast_channel_linkedid(chan), sizeof(fork_expected_one.linkedid));
2196 ast_copy_string(fork_expected_two.uniqueid, ast_channel_uniqueid(chan), sizeof(fork_expected_two.uniqueid));
2197 ast_copy_string(fork_expected_two.linkedid, ast_channel_linkedid(chan), sizeof(fork_expected_two.linkedid));
2198
2199 /* Channel enters Wait app */
2200 ast_channel_lock(chan);
2201 ast_channel_appl_set(chan, "Wait");
2202 ast_channel_data_set(chan, "10");
2203 ast_channel_priority_set(chan, 1);
2205
2206 /* Set properties on the channel that propagate to the CDR */
2208 ast_channel_accountcode_set(chan, "XXX");
2209 ast_channel_unlock(chan);
2210
2211 /* Wait one second so we get a duration. */
2213
2214 ast_cdr_setuserfield(ast_channel_name(chan), "foobar");
2215 ast_test_validate(test, ast_cdr_setvar(ast_channel_name(chan), "test_variable", "record_1") == 0);
2216
2217 /* Verify that we can't set read-only fields or other fields directly */
2218 ast_test_validate(test, ast_cdr_setvar(ast_channel_name(chan), "clid", "junk") != 0);
2219 ast_test_validate(test, ast_cdr_setvar(ast_channel_name(chan), "src", "junk") != 0);
2220 ast_test_validate(test, ast_cdr_setvar(ast_channel_name(chan), "dst", "junk") != 0);
2221 ast_test_validate(test, ast_cdr_setvar(ast_channel_name(chan), "dcontext", "junk") != 0);
2222 ast_test_validate(test, ast_cdr_setvar(ast_channel_name(chan), "channel", "junk") != 0);
2223 ast_test_validate(test, ast_cdr_setvar(ast_channel_name(chan), "dstchannel", "junk") != 0);
2224 ast_test_validate(test, ast_cdr_setvar(ast_channel_name(chan), "lastapp", "junk") != 0);
2225 ast_test_validate(test, ast_cdr_setvar(ast_channel_name(chan), "lastdata", "junk") != 0);
2226 ast_test_validate(test, ast_cdr_setvar(ast_channel_name(chan), "start", "junk") != 0);
2227 ast_test_validate(test, ast_cdr_setvar(ast_channel_name(chan), "answer", "junk") != 0);
2228 ast_test_validate(test, ast_cdr_setvar(ast_channel_name(chan), "end", "junk") != 0);
2229 ast_test_validate(test, ast_cdr_setvar(ast_channel_name(chan), "duration", "junk") != 0);
2230 ast_test_validate(test, ast_cdr_setvar(ast_channel_name(chan), "billsec", "junk") != 0);
2231 ast_test_validate(test, ast_cdr_setvar(ast_channel_name(chan), "disposition", "junk") != 0);
2232 ast_test_validate(test, ast_cdr_setvar(ast_channel_name(chan), "amaflags", "junk") != 0);
2233 ast_test_validate(test, ast_cdr_setvar(ast_channel_name(chan), "accountcode", "junk") != 0);
2234 ast_test_validate(test, ast_cdr_setvar(ast_channel_name(chan), "uniqueid", "junk") != 0);
2235 ast_test_validate(test, ast_cdr_setvar(ast_channel_name(chan), "linkedid", "junk") != 0);
2236 ast_test_validate(test, ast_cdr_setvar(ast_channel_name(chan), "userfield", "junk") != 0);
2237 ast_test_validate(test, ast_cdr_setvar(ast_channel_name(chan), "sequence", "junk") != 0);
2238
2239 /* Verify the values */
2240 ast_test_validate(test, ast_cdr_getvar(ast_channel_name(chan), "userfield", varbuffer, sizeof(varbuffer)) == 0);
2241 ast_test_validate(test, strcmp(varbuffer, "foobar") == 0);
2242 ast_test_validate(test, ast_cdr_getvar(ast_channel_name(chan), "test_variable", varbuffer, sizeof(varbuffer)) == 0);
2243 ast_test_validate(test, strcmp(varbuffer, "record_1") == 0);
2244 ast_test_validate(test, ast_cdr_getvar(ast_channel_name(chan), "amaflags", varbuffer, sizeof(varbuffer)) == 0);
2245 sscanf(varbuffer, "%d", &int_buffer);
2246 ast_test_validate(test, int_buffer == AST_AMA_OMIT);
2247 ast_test_validate(test, ast_cdr_getvar(ast_channel_name(chan), "accountcode", varbuffer, sizeof(varbuffer)) == 0);
2248 ast_test_validate(test, strcmp(varbuffer, "XXX") == 0);
2249 ast_test_validate(test, ast_cdr_getvar(ast_channel_name(chan), "clid", varbuffer, sizeof(varbuffer)) == 0);
2250 ast_test_validate(test, strcmp(varbuffer, "\"Alice\" <100>") == 0);
2251 ast_test_validate(test, ast_cdr_getvar(ast_channel_name(chan), "src", varbuffer, sizeof(varbuffer)) == 0);
2252 ast_test_validate(test, strcmp(varbuffer, "100") == 0);
2253 ast_test_validate(test, ast_cdr_getvar(ast_channel_name(chan), "dst", varbuffer, sizeof(varbuffer)) == 0);
2254 ast_test_validate(test, strcmp(varbuffer, "100") == 0);
2255 ast_test_validate(test, ast_cdr_getvar(ast_channel_name(chan), "dcontext", varbuffer, sizeof(varbuffer)) == 0);
2256 ast_test_validate(test, strcmp(varbuffer, "default") == 0);
2257 ast_test_validate(test, ast_cdr_getvar(ast_channel_name(chan), "channel", varbuffer, sizeof(varbuffer)) == 0);
2258 ast_test_validate(test, strcmp(varbuffer, CHANNEL_TECH_NAME "/Alice") == 0);
2259 ast_test_validate(test, ast_cdr_getvar(ast_channel_name(chan), "dstchannel", varbuffer, sizeof(varbuffer)) == 0);
2260 ast_test_validate(test, strcmp(varbuffer, "") == 0);
2261 ast_test_validate(test, ast_cdr_getvar(ast_channel_name(chan), "lastapp", varbuffer, sizeof(varbuffer)) == 0);
2262 ast_test_validate(test, strcmp(varbuffer, "Wait") == 0);
2263 ast_test_validate(test, ast_cdr_getvar(ast_channel_name(chan), "lastdata", varbuffer, sizeof(varbuffer)) == 0);
2264 ast_test_validate(test, strcmp(varbuffer, "10") == 0);
2265 ast_test_validate(test, ast_cdr_getvar(ast_channel_name(chan), "start", varbuffer, sizeof(varbuffer)) == 0);
2266 sscanf(varbuffer, "%lf", &db_buffer);
2267 ast_test_validate(test, fabs(db_buffer) > 0);
2268 ast_test_validate(test, ast_cdr_getvar(ast_channel_name(chan), "answer", varbuffer, sizeof(varbuffer)) == 0);
2269 sscanf(varbuffer, "%lf", &db_buffer);
2270 ast_test_validate(test, fabs(db_buffer) < EPSILON);
2271 ast_test_validate(test, ast_cdr_getvar(ast_channel_name(chan), "end", varbuffer, sizeof(varbuffer)) == 0);
2272 sscanf(varbuffer, "%lf", &db_buffer);
2273 ast_test_validate(test, fabs(db_buffer) < EPSILON);
2274 ast_test_validate(test, ast_cdr_getvar(ast_channel_name(chan), "duration", varbuffer, sizeof(varbuffer)) == 0);
2275 sscanf(varbuffer, "%lf", &db_buffer);
2276 ast_test_validate(test, fabs(db_buffer) > 0);
2277 ast_test_validate(test, ast_cdr_getvar(ast_channel_name(chan), "billsec", varbuffer, sizeof(varbuffer)) == 0);
2278 sscanf(varbuffer, "%lf", &db_buffer);
2279 ast_test_validate(test, fabs(db_buffer) < EPSILON);
2280 ast_test_validate(test, ast_cdr_getvar(ast_channel_name(chan), "disposition", varbuffer, sizeof(varbuffer)) == 0);
2281 sscanf(varbuffer, "%d", &int_buffer);
2282 ast_test_validate(test, int_buffer == AST_CDR_NULL);
2283 ast_test_validate(test, ast_cdr_getvar(ast_channel_name(chan), "uniqueid", varbuffer, sizeof(varbuffer)) == 0);
2284 ast_test_validate(test, strcmp(varbuffer, ast_channel_uniqueid(chan)) == 0);
2285 ast_test_validate(test, ast_cdr_getvar(ast_channel_name(chan), "linkedid", varbuffer, sizeof(varbuffer)) == 0);
2286 ast_test_validate(test, strcmp(varbuffer, ast_channel_linkedid(chan)) == 0);
2287 ast_test_validate(test, ast_cdr_getvar(ast_channel_name(chan), "sequence", varbuffer, sizeof(varbuffer)) == 0);
2288
2289 /* Fork the CDR, and check that we change the properties on both CDRs. */
2290 ast_set_flag(&fork_options, AST_CDR_FLAG_KEEP_VARS);
2291 ast_test_validate(test, ast_cdr_fork(ast_channel_name(chan), &fork_options) == 0);
2292
2293 /* Change some properties */
2294 ast_cdr_setuserfield(ast_channel_name(chan), "yackity");
2295 ast_test_validate(test, ast_cdr_setvar(ast_channel_name(chan), "test_variable", "record_1b") == 0);
2296
2297 /* Fork the CDR again, finalizing all current CDRs */
2299 ast_test_validate(test, ast_cdr_fork(ast_channel_name(chan), &fork_options) == 0);
2300
2301 /* Channel enters Answer app */
2302 ast_channel_lock(chan);
2303 ast_channel_appl_set(chan, "Answer");
2304 ast_channel_data_set(chan, "");
2305 ast_channel_priority_set(chan, 1);
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:3539
int ast_cdr_setvar(const char *channel_name, const char *name, const char *value)
Set a variable on a CDR.
Definition: cdr.c:3240
@ AST_CDR_NULL
Definition: cdr.h:258
@ AST_CDR_FLAG_FINALIZE
Definition: cdr.h:247
@ AST_CDR_FLAG_KEEP_VARS
Definition: cdr.h:243
int ast_cdr_fork(const char *channel_name, struct ast_flags *options)
Fork a CDR.
Definition: cdr.c:3699
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:3386
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:2541
#define ast_channel_lock(chan)
Definition: channel.h:2922
void ast_channel_data_set(struct ast_channel *chan, const char *value)
@ AST_AMA_OMIT
Definition: channel.h:1179
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:7385
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:199
#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, sip_to_pjsip::info(), ast_cdr::linkedid, ast_cdr::next, NULL, RAII_VAR, result, safe_channel_release(), SWAP_CONFIG, TEST_CATEGORY, TEST_EXECUTE, TEST_INIT, to_sleep, unanswered_cdr_config, ast_cdr::uniqueid, 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;
2441 original.next = &fork_expected_one;
2442 fork_expected_one.next = &fork_expected_two;
2443
2444 switch (cmd) {
2445 case TEST_INIT:
2446 info->name = __func__;
2447 info->category = TEST_CATEGORY;
2448 info->summary = "Test field access CDRs";
2449 info->description =
2450 "This tests setting/retrieving data on CDR records.";
2451 return AST_TEST_NOT_RUN;
2452 case TEST_EXECUTE:
2453 break;
2454 }
2455
2457
2458 CREATE_ALICE_CHANNEL(chan, &caller, &original);
2459 ast_copy_string(fork_expected_one.uniqueid, ast_channel_uniqueid(chan), sizeof(fork_expected_one.uniqueid));
2460 ast_copy_string(fork_expected_one.linkedid, ast_channel_linkedid(chan), sizeof(fork_expected_one.linkedid));
2461 ast_copy_string(fork_expected_two.uniqueid, ast_channel_uniqueid(chan), sizeof(fork_expected_two.uniqueid));
2462 ast_copy_string(fork_expected_two.linkedid, ast_channel_linkedid(chan), sizeof(fork_expected_two.linkedid));
2463
2465
2466 /* Test blowing away variables */
2467 ast_test_validate(test, ast_cdr_setvar(ast_channel_name(chan), "test_variable", "record_1") == 0);
2468 ast_test_validate(test, ast_cdr_getvar(ast_channel_name(chan), "test_variable", varbuffer, sizeof(varbuffer)) == 0);
2469 ast_test_validate(test, strcmp(varbuffer, "record_1") == 0);
2470 ast_copy_string(varbuffer, "", sizeof(varbuffer));
2471
2472 ast_test_validate(test, ast_cdr_fork(ast_channel_name(chan), &fork_options) == 0);
2473 ast_test_validate(test, ast_cdr_getvar(ast_channel_name(chan), "test_variable", fork_varbuffer, sizeof(fork_varbuffer)) == 0);
2474 ast_test_validate(test, strcmp(varbuffer, "record_1") != 0);
2475
2476 /* Test finalizing previous CDRs */
2477 ast_set_flag(&fork_options, AST_CDR_FLAG_FINALIZE);
2478 ast_test_validate(test, ast_cdr_fork(ast_channel_name(chan), &fork_options) == 0);
2479
2480 /* Test keep variables; setting a new answer time */
2481 ast_channel_lock(chan);
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);
2488 ast_test_validate(test, ast_cdr_getvar(ast_channel_name(chan), "answer", answer_time, sizeof(answer_time)) == 0);
2489 ast_test_validate(test, ast_cdr_getvar(ast_channel_name(chan), "start", start_time, sizeof(start_time)) == 0);
2490
2491 ast_set_flag(&fork_options, AST_CDR_FLAG_FINALIZE);
2492 ast_set_flag(&fork_options, AST_CDR_FLAG_KEEP_VARS);
2493 ast_set_flag(&fork_options, AST_CDR_FLAG_SET_ANSWER);
2494 ast_test_validate(test, ast_cdr_fork(ast_channel_name(chan), &fork_options) == 0);
2495 ast_test_validate(test, ast_cdr_getvar(ast_channel_name(chan), "answer", fork_answer_time, sizeof(fork_answer_time)) == 0);
2496 ast_test_validate(test, ast_cdr_getvar(ast_channel_name(chan), "start", fork_start_time, sizeof(fork_start_time)) == 0);
2497 ast_test_validate(test, ast_cdr_getvar(ast_channel_name(chan), "test_variable", fork_varbuffer, sizeof(fork_varbuffer)) == 0);
2498 ast_test_validate(test, strcmp(fork_varbuffer, varbuffer) == 0);
2499 ast_test_validate(test, strcmp(fork_start_time, start_time) == 0);
2500 ast_test_validate(test, strcmp(fork_answer_time, answer_time) != 0);
2501
2503 ast_set_flag(&fork_options, AST_CDR_FLAG_RESET);
2504 ast_test_validate(test, ast_cdr_fork(ast_channel_name(chan), &fork_options) == 0);
2505 ast_test_validate(test, ast_cdr_getvar(ast_channel_name(chan), "answer", fork_answer_time, sizeof(fork_answer_time)) == 0);
2506 ast_test_validate(test, ast_cdr_getvar(ast_channel_name(chan), "start", fork_start_time, sizeof(fork_start_time)) == 0);
2507 ast_test_validate(test, strcmp(fork_start_time, start_time) != 0);
2508 ast_test_validate(test, strcmp(fork_answer_time, answer_time) != 0);
2509
2511 ast_hangup(chan);
2512 chan = NULL;
2513 result = verify_mock_cdr_record(test, expected, 3);
2514
2515 return result;
2516}
@ AST_CDR_FLAG_RESET
Definition: cdr.h:249
@ AST_CDR_FLAG_SET_ANSWER
Definition: cdr.h:248

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(), sip_to_pjsip::info(), ast_cdr::linkedid, ast_cdr::next, NULL, RAII_VAR, result, safe_channel_release(), SWAP_CONFIG, TEST_CATEGORY, TEST_EXECUTE, TEST_INIT, to_sleep, ast_cdr::uniqueid, 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 */
2365 ast_test_validate(test, ast_cdr_set_property(ast_channel_name(chan), AST_CDR_FLAG_DISABLE) == 0);
2366
2367 /* Fork the CDR. This should be enabled */
2368 ast_set_flag(&fork_options, AST_CDR_FLAG_FINALIZE);
2369 ast_test_validate(test, ast_cdr_fork(ast_channel_name(chan), &fork_options) == 0);
2370
2371 /* Disable and enable the forked CDR */
2372 ast_test_validate(test, ast_cdr_set_property(ast_channel_name(chan), AST_CDR_FLAG_DISABLE) == 0);
2373 ast_test_validate(test, ast_cdr_clear_property(ast_channel_name(chan), AST_CDR_FLAG_DISABLE) == 0);
2374
2375 /* Fork and finalize again. This CDR should be propagated */
2376 ast_test_validate(test, ast_cdr_fork(ast_channel_name(chan), &fork_options) == 0);
2377
2378 /* Disable all future CDRs */
2379 ast_test_validate(test, ast_cdr_set_property(ast_channel_name(chan), AST_CDR_FLAG_DISABLE_ALL) == 0);
2380
2381 /* Fork a few more */
2382 ast_test_validate(test, ast_cdr_fork(ast_channel_name(chan), &fork_options) == 0);
2383 ast_test_validate(test, ast_cdr_fork(ast_channel_name(chan), &fork_options) == 0);
2384 ast_test_validate(test, ast_cdr_fork(ast_channel_name(chan), &fork_options) == 0);
2385
2387 ast_hangup(chan);
2388 chan = NULL;
2389 result = verify_mock_cdr_record(test, &expected, 1);
2390
2391 return result;
2392}
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:3637
@ AST_CDR_FLAG_DISABLE_ALL
Definition: cdr.h:245
@ AST_CDR_FLAG_DISABLE
Definition: cdr.h:244
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:3610

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(), sip_to_pjsip::info(), NULL, RAII_VAR, result, safe_channel_release(), 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
592 CREATE_ALICE_CHANNEL(chan_alice, &caller, &alice_expected);
594
595 bridge = ast_bridge_basic_new();
596 ast_test_validate(test, bridge != NULL);
598
599 ast_test_validate(test, !ast_bridge_impart(bridge, chan_alice, NULL, NULL, AST_BRIDGE_IMPART_CHAN_DEPARTABLE));
600
601 chan_bob = ast_channel_alloc(0, AST_STATE_DOWN, NULL, NULL, "200", NULL, NULL, NULL, chan_alice, 0, CHANNEL_TECH_NAME "/Bob");
602 SET_FORMATS(chan_bob);
603 ast_channel_unlock(chan_bob);
604 ast_copy_string(bob_expected.linkedid, ast_channel_linkedid(chan_bob), sizeof(bob_expected.linkedid));
605 ast_copy_string(bob_expected.uniqueid, ast_channel_uniqueid(chan_bob), sizeof(bob_expected.uniqueid));
608 EMULATE_APP_DATA(chan_bob, 0, "AppDial", "(Outgoing Line)");
609
610 ast_channel_publish_dial(NULL, chan_bob, "Bob", NULL);
612 ast_channel_publish_dial(NULL, chan_bob, NULL, "ANSWER");
613
615
617
618 ast_test_validate(test, !ast_bridge_impart(bridge, chan_bob, NULL, NULL, AST_BRIDGE_IMPART_CHAN_DEPARTABLE));
619
621
622 ast_bridge_depart(chan_bob);
623 ast_bridge_depart(chan_alice);
624
626 HANGUP_CHANNEL(chan_alice, AST_CAUSE_NORMAL);
627
628 result = verify_mock_cdr_record(test, &bob_expected, 2);
629 return result;
630}
@ AST_FLAG_ORIGINATED
Definition: channel.h:1039

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, sip_to_pjsip::info(), ast_cdr::linkedid, NULL, RAII_VAR, result, safe_bridge_destroy(), safe_channel_release(), SET_FORMATS, SWAP_CONFIG, TEST_CATEGORY, TEST_EXECUTE, TEST_INIT, to_sleep, ast_cdr::uniqueid, 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 }
2083 CREATE_ALICE_CHANNEL(chan_alice, &alice_caller, &alice_expected);
2084 CREATE_BOB_CHANNEL(chan_bob, &bob_caller, &bob_expected);
2085
2086 ast_channel_lock(chan_alice);
2087 EMULATE_APP_DATA(chan_alice, 1, "Park", "700");
2088 ast_setstate(chan_alice, AST_STATE_UP);
2089 ast_channel_unlock(chan_alice);
2090
2091 ast_channel_lock(chan_bob);
2092 EMULATE_APP_DATA(chan_bob, 1, "Park", "701");
2093 ast_setstate(chan_bob, AST_STATE_UP);
2094 ast_channel_unlock(chan_bob);
2095
2099 "test_cdr", "test_cdr_park", NULL);
2100 ast_test_validate(test, bridge != NULL);
2101
2103 ast_test_validate(test, !ast_bridge_impart(bridge, chan_alice, NULL, NULL, AST_BRIDGE_IMPART_CHAN_DEPARTABLE));
2105 ast_test_validate(test, !ast_bridge_impart(bridge, chan_bob, NULL, NULL, AST_BRIDGE_IMPART_CHAN_DEPARTABLE));
2107 ast_bridge_depart(chan_alice);
2108 ast_bridge_depart(chan_bob);
2109
2110 /* And then it hangs up */
2111 HANGUP_CHANNEL(chan_alice, AST_CAUSE_NORMAL);
2113
2114 result = verify_mock_cdr_record(test, &alice_expected, 2);
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:934
@ AST_BRIDGE_CAPABILITY_HOLDING
Definition: bridge.h:86
@ 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, sip_to_pjsip::info(), NULL, RAII_VAR, result, safe_bridge_destroy(), safe_channel_release(), 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
732 ast_test_validate(test, !ast_bridge_impart(bridge, chan, NULL, NULL, AST_BRIDGE_IMPART_CHAN_DEPARTABLE));
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, sip_to_pjsip::info(), NULL, RAII_VAR, result, safe_bridge_destroy(), safe_channel_release(), 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
808 ast_test_validate(test, !ast_bridge_impart(bridge, chan, NULL, NULL, AST_BRIDGE_IMPART_CHAN_DEPARTABLE));
809
811
812 ast_bridge_depart(chan);
813
814 EMULATE_APP_DATA(chan, 3, "Wait", "");
815
816 /* And then it hangs up */
818
819 result = verify_mock_cdr_record(test, &expected_one, 2);
820
821 return result;
822}

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, sip_to_pjsip::info(), NULL, RAII_VAR, result, safe_bridge_destroy(), safe_channel_release(), 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 }
1096 CREATE_ALICE_CHANNEL(chan_alice, &caller_alice, &alice_expected_one);
1097 COPY_IDS(chan_alice, &alice_expected_two);
1098 CREATE_BOB_CHANNEL(chan_bob, &caller_bob, &bob_expected);
1099 ast_copy_string(bob_expected.linkedid, ast_channel_linkedid(chan_alice), sizeof(bob_expected.linkedid));
1100 CREATE_CHARLIE_CHANNEL(chan_charlie, &caller_charlie, &charlie_expected);
1101 ast_copy_string(charlie_expected.linkedid, ast_channel_linkedid(chan_alice), sizeof(charlie_expected.linkedid));
1102
1103 ast_channel_lock(chan_alice);
1104 EMULATE_APP_DATA(chan_alice, 1, "Answer", "");
1105 ast_setstate(chan_alice, AST_STATE_UP);
1106 EMULATE_APP_DATA(chan_alice, 2, "Bridge", "");
1107 ast_channel_unlock(chan_alice);
1108
1109 bridge = ast_bridge_basic_new();
1110 ast_test_validate(test, bridge != NULL);
1112
1113 ast_test_validate(test, !ast_bridge_impart(bridge, chan_alice, NULL, NULL, AST_BRIDGE_IMPART_CHAN_DEPARTABLE));
1114
1115 ast_channel_lock(chan_bob);
1116 EMULATE_APP_DATA(chan_bob, 1, "Answer", "");
1117 ast_setstate(chan_bob, AST_STATE_UP);
1118 EMULATE_APP_DATA(chan_bob, 2, "Bridge", "");
1119 ast_channel_unlock(chan_bob);
1121
1122 ast_test_validate(test, !ast_bridge_impart(bridge, chan_bob, NULL, NULL, AST_BRIDGE_IMPART_CHAN_DEPARTABLE));
1123
1125
1126 ast_channel_lock(chan_charlie);
1127 EMULATE_APP_DATA(chan_charlie, 1, "Answer", "");
1128 ast_setstate(chan_charlie, AST_STATE_UP);
1129 EMULATE_APP_DATA(chan_charlie, 2, "Bridge", "");
1130 ast_channel_unlock(chan_charlie);
1131 ast_test_validate(test, !ast_bridge_impart(bridge, chan_charlie, NULL, NULL, AST_BRIDGE_IMPART_CHAN_DEPARTABLE));
1132
1134
1135 ast_bridge_depart(chan_alice);
1136 ast_bridge_depart(chan_bob);
1137 ast_bridge_depart(chan_charlie);
1138
1139 HANGUP_CHANNEL(chan_alice, AST_CAUSE_NORMAL);
1141 HANGUP_CHANNEL(chan_charlie, AST_CAUSE_NORMAL);
1142
1143 result = verify_mock_cdr_record(test, &alice_expected_one, 4);
1144
1145 return result;
1146}

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, sip_to_pjsip::info(), ast_cdr::linkedid, NULL, RAII_VAR, result, safe_bridge_destroy(), safe_channel_release(), 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, sip_to_pjsip::info(), NULL, RAII_VAR, result, safe_channel_release(), 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 }
879 CREATE_ALICE_CHANNEL(chan_alice, &caller_alice, &alice_expected);
880
881 CREATE_BOB_CHANNEL(chan_bob, &caller_bob, &bob_expected);
882 ast_copy_string(bob_expected.linkedid, ast_channel_linkedid(chan_alice), sizeof(bob_expected.linkedid));
883
884 ast_channel_lock(chan_alice);
885 EMULATE_APP_DATA(chan_alice, 1, "Answer", "");
886 ast_setstate(chan_alice, AST_STATE_UP);
887 EMULATE_APP_DATA(chan_alice, 2, "Bridge", "");
888 ast_channel_unlock(chan_alice);
889
890 bridge = ast_bridge_basic_new();
891 ast_test_validate(test, bridge != NULL);
892
893 ast_test_validate(test, !ast_bridge_impart(bridge, chan_alice, NULL, NULL, AST_BRIDGE_IMPART_CHAN_DEPARTABLE));
895
896 ast_channel_lock(chan_bob);
897 EMULATE_APP_DATA(chan_bob, 1, "Answer", "");
898 ast_setstate(chan_bob, AST_STATE_UP);
899 EMULATE_APP_DATA(chan_bob, 2, "Bridge", "");
900 ast_channel_unlock(chan_bob);
901
902 ast_test_validate(test, !ast_bridge_impart(bridge, chan_bob, NULL, NULL, AST_BRIDGE_IMPART_CHAN_DEPARTABLE));
904
905 ast_bridge_depart(chan_alice);
906 ast_bridge_depart(chan_bob);
907
908 HANGUP_CHANNEL(chan_alice, AST_CAUSE_NORMAL);
910
911 result = verify_mock_cdr_record(test, &alice_expected, 2);
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, sip_to_pjsip::info(), ast_cdr::linkedid, NULL, RAII_VAR, result, safe_bridge_destroy(), safe_channel_release(), 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 }
971 CREATE_ALICE_CHANNEL(chan_alice, &caller_alice, &alice_expected);
972
973 CREATE_BOB_CHANNEL(chan_bob, &caller_bob, &bob_expected);
974 ast_copy_string(bob_expected.linkedid, ast_channel_linkedid(chan_alice), sizeof(bob_expected.linkedid));
975
976 ast_channel_unlock(chan_alice);
977 EMULATE_APP_DATA(chan_alice, 1, "Answer", "");
978 ast_setstate(chan_alice, AST_STATE_UP);
979 EMULATE_APP_DATA(chan_alice, 2, "Bridge", "");
980 ast_channel_unlock(chan_alice);
981
982 bridge = ast_bridge_basic_new();
983 ast_test_validate(test, bridge != NULL);
984
985 ast_channel_lock(chan_bob);
986 EMULATE_APP_DATA(chan_bob, 1, "Answer", "");
987 ast_setstate(chan_bob, AST_STATE_UP);
988 EMULATE_APP_DATA(chan_bob, 2, "Bridge", "");
989 ast_channel_unlock(chan_bob);
991
992 ast_test_validate(test, !ast_bridge_impart(bridge, chan_bob, NULL, NULL, AST_BRIDGE_IMPART_CHAN_DEPARTABLE));
994
995 ast_test_validate(test, !ast_bridge_impart(bridge, chan_alice, NULL, NULL, AST_BRIDGE_IMPART_CHAN_DEPARTABLE));
997
998 ast_bridge_depart(chan_alice);
999 ast_bridge_depart(chan_bob);
1000
1001 HANGUP_CHANNEL(chan_alice, AST_CAUSE_NORMAL);
1003
1004 result = verify_mock_cdr_record(test, &alice_expected, 2);
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, sip_to_pjsip::info(), ast_cdr::linkedid, NULL, RAII_VAR, result, safe_bridge_destroy(), safe_channel_release(), 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, sip_to_pjsip::info(), NULL, RAII_VAR, result, safe_channel_release(), 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:420
struct ast_party_name name
Subscriber name.
Definition: channel.h:340
char * str
Subscriber name (Malloced)
Definition: channel.h:264

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, sip_to_pjsip::info(), ast_party_id::name, NULL, RAII_VAR, result, safe_channel_release(), 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:3473
#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.
Definition: linkedlists.h:833
#define AST_LIST_UNLOCK(head)
Attempts to unlock a list.
Definition: linkedlists.h:140
Definition: test_cdr.c:96
struct ast_cdr * cdr
Definition: test_cdr.c:97
struct test_cdr_entry::@493 list
static struct @492 actual_cdr_entries
A linked list of received CDR entries from the engine.
static int global_mock_cdr_count
The number of CDRs the mock backend has received.
Definition: test_cdr.c:102

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.

Referenced by AST_TEST_DEFINE().

◆ 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:3005
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:201
@ 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, 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.
Definition: linkedlists.h:491
#define AST_LIST_INSERT_TAIL(head, elm, field)
Appends a list entry to the tail of a list.
Definition: linkedlists.h:731
#define ast_cond_signal(cond)
Definition: lock.h:203
struct varshead varshead
Definition: cdr.h:326
char name[0]
Definition: chanvars.h:31
char * value
Definition: chanvars.h:30
struct ast_var_t::@211 entries
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_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:944

References ast_bridge_destroy().

Referenced by AST_TEST_DEFINE().

◆ safe_channel_release()

static void safe_channel_release ( struct ast_channel chan)
static

Definition at line 371 of file test_cdr.c.

372{
373 if (!chan) {
374 return;
375 }
377}
struct ast_channel * ast_channel_release(struct ast_channel *chan)
Unlink and release reference to a channel.
Definition: channel.c:1584

References ast_channel_release().

Referenced by AST_TEST_DEFINE().

◆ 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:2902
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:2888

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:3050
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, 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:479
static char accountcode[AST_MAX_ACCOUNT_CODE]
Definition: chan_iax2.c:476
static int answer(void *data)
Definition: chan_pjsip.c:683
char * end
Definition: eagi_proxy.c:73
#define ast_cond_timedwait(cond, mutex, time)
Definition: lock.h:206
#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:291
long int billsec
Definition: cdr.h:305
char channel[AST_MAX_EXTENSION]
Definition: cdr.h:289
#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
@ AST_TEST_FAIL
Definition: test.h:196
#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().

Variable Documentation

◆ __mod_info

struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_LOAD_ORDER , .description = "CDR unit tests" , .key = "This paragraph is copyright (c) 2006 by Digium, Inc. \In order for your module to load, it must return this \key via a function called \"key\". Any code which \includes this paragraph must be licensed under the GNU \General Public License version 2 or later (at your \option). In addition to Digium's general reservations \of rights, Digium expressly reserves the right to \allow other parties to license this paragraph under \different terms. Any use of Digium, Inc. trademarks or \logos (including \"Asterisk\" or \"Digium\") without \express written permission of Digium, Inc. is prohibited.\n" , .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 { ... } 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:
= {
}
@ 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
@ CDR_DEBUG
Definition: cdr.h:226

A configuration suitable for CDRs with congestion enabled.

Definition at line 71 of file test_cdr.c.

Referenced by AST_TEST_DEFINE().

◆ debug_cdr_config

struct ast_cdr_config debug_cdr_config
static
Initial value:
= {
}

A configuration suitable for 'normal' CDRs.

Definition at line 61 of file test_cdr.c.

Referenced by AST_TEST_DEFINE().

◆ 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.

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.

Referenced by AST_TEST_DEFINE().