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

CEL unit tests. More...

#include "asterisk.h"
#include <math.h>
#include "asterisk/module.h"
#include "asterisk/test.h"
#include "asterisk/cel.h"
#include "asterisk/channel.h"
#include "asterisk/format_cache.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/pickup.h"
#include "asterisk/stasis_channels.h"
#include "asterisk/stasis_bridges.h"
#include "asterisk/json.h"
#include "asterisk/features.h"
#include "asterisk/core_local.h"
Include dependency graph for test_cel.c:

Go to the source code of this file.

Macros

#define ALICE_CALLERID   { .id.name.str = "Alice", .id.name.valid = 1, .id.number.str = "100", .id.number.valid = 1, }
 Alice's Caller ID.
 
#define ANSWER_CHANNEL(chan)
 
#define ANSWER_NO_APP(chan)
 
#define APPEND_DUMMY_EVENT()
 
#define APPEND_EVENT(chan, ev_type, userevent, extra)
 
#define APPEND_EVENT_PEER(chan, ev_type, userevent, extra, peer)
 
#define APPEND_EVENT_SNAPSHOT(snapshot, ev_type, userevent, extra, peer)
 
#define ATTENDEDTRANSFER_BRIDGE(channel1, bridge1, channel2, bridge2, channel3, channel4)
 
#define BLINDTRANSFER_EVENT(channel, bridge, extension, context)
 
#define BOB_CALLERID   { .id.name.str = "Bob", .id.name.valid = 1, .id.number.str = "200", .id.number.valid = 1, }
 Bob's Caller ID.
 
#define BRIDGE_ENTER(channel, bridge)
 
#define BRIDGE_ENTER_EVENT(channel, bridge)
 
#define BRIDGE_ENTER_EVENT_PEER(channel, bridge, peer)
 
#define BRIDGE_EXIT(channel, bridge)
 
#define BRIDGE_EXIT_EVENT(channel, bridge)
 
#define BRIDGE_EXIT_EVENT_PEER(channel, bridge, peer)
 
#define BRIDGE_EXIT_SNAPSHOT(channel, bridge)
 
#define CHANNEL_TECH_NAME   "CELTestChannel"
 
#define CHARLIE_CALLERID   { .id.name.str = "Charlie", .id.name.valid = 1, .id.number.str = "300", .id.number.valid = 1, }
 Charlie's Caller ID.
 
#define CREATE_ALICE_CHANNEL(channel_var, caller_id)
 Create a test_cel_chan_tech for Alice.
 
#define CREATE_BOB_CHANNEL(channel_var, caller_id)
 Create a test_cel_chan_tech for Bob.
 
#define CREATE_CHARLIE_CHANNEL(channel_var, caller_id)
 Create a test_cel_chan_tech for Charlie.
 
#define CREATE_DAVID_CHANNEL(channel_var, caller_id)
 Create a test_cel_chan_tech for David.
 
#define DAVID_CALLERID   { .id.name.str = "David", .id.name.valid = 1, .id.number.str = "400", .id.number.valid = 1, }
 David's Caller ID.
 
#define EMULATE_APP_DATA(channel, priority, application, data)
 Emulate a channel entering into an application.
 
#define EMULATE_DIAL(channel, dialstring)
 
#define HANGUP_CHANNEL(channel, cause, dialstatus)
 Hang up a test channel safely.
 
#define HANGUP_EVENT(channel, cause, dialstatus)
 
#define SET_FORMATS(chan)
 Set ulaw format on channel.
 
#define START_DIALED(caller, callee)    START_DIALED_FULL(caller, callee, "200", "Bob")
 
#define START_DIALED_FULL(caller, callee, number, name)
 
#define TEST_BACKEND_NAME   "CEL Test Logging"
 
#define TEST_CATEGORY   "/main/cel/"
 

Functions

static void __reg_module (void)
 
static struct ast_str__test_cel_generate_peer_str (struct ast_channel_snapshot *chan, struct ast_bridge_snapshot *bridge)
 
static void __unreg_module (void)
 
static struct ast_eventao2_dup_event (const struct ast_event *event)
 
static int append_event (struct ast_event *ev)
 
static int append_expected_event (struct ast_channel *chan, enum ast_cel_event_type type, const char *userdefevname, struct ast_json *extra, const char *peer)
 
static int append_expected_event_snapshot (struct ast_channel_snapshot *snapshot, enum ast_cel_event_type type, const char *userdefevname, struct ast_json *extra, const char *peer)
 
struct ast_moduleAST_MODULE_SELF_SYM (void)
 
 AST_TEST_DEFINE (test_cel_attended_transfer_bridges_merge)
 
 AST_TEST_DEFINE (test_cel_blind_transfer)
 
 AST_TEST_DEFINE (test_cel_channel_creation)
 
 AST_TEST_DEFINE (test_cel_dial_answer_no_bridge)
 
 AST_TEST_DEFINE (test_cel_dial_answer_twoparty_bridge_a)
 
 AST_TEST_DEFINE (test_cel_dial_answer_twoparty_bridge_b)
 
 AST_TEST_DEFINE (test_cel_dial_busy)
 
 AST_TEST_DEFINE (test_cel_dial_caller_cancel)
 
 AST_TEST_DEFINE (test_cel_dial_congestion)
 
 AST_TEST_DEFINE (test_cel_dial_parallel_failed)
 
 AST_TEST_DEFINE (test_cel_dial_pickup)
 
 AST_TEST_DEFINE (test_cel_dial_unanswered)
 
 AST_TEST_DEFINE (test_cel_dial_unanswered_filter)
 
 AST_TEST_DEFINE (test_cel_dial_unavailable)
 
 AST_TEST_DEFINE (test_cel_local_optimize)
 
 AST_TEST_DEFINE (test_cel_single_bridge)
 
 AST_TEST_DEFINE (test_cel_single_bridge_continue)
 
 AST_TEST_DEFINE (test_cel_single_party)
 
 AST_TEST_DEFINE (test_cel_single_twoparty_bridge_a)
 
 AST_TEST_DEFINE (test_cel_single_twoparty_bridge_b)
 
 AST_TEST_DEFINE (test_cel_unanswered_inbound_call)
 
 AST_TEST_DEFINE (test_cel_unanswered_outbound_call)
 
static int cel_verify_and_cleanup_cb (struct ast_test_info *info, struct ast_test *test)
 
static int check_events (struct ast_test *test, struct ao2_container *local_expected, struct ao2_container *local_received)
 
static void do_sleep (void)
 
static int dump_event (struct ast_test *test, struct ast_event *event)
 
static int events_are_equal (struct ast_test *test, struct ast_event *received, struct ast_event *expected)
 
static int load_module (void)
 
static int match_ie_val (const struct ast_event *event1, const struct ast_event *event2, enum ast_event_ie_type type)
 Check an IE value from two events.
 
static void mid_test_sync (void)
 
static void safe_bridge_destroy (struct ast_bridge *bridge)
 
static void safe_channel_release (struct ast_channel *chan)
 
static struct ast_strtest_cel_generate_peer_str (struct ast_channel *chan, struct ast_bridge *bridge)
 
static struct ast_strtest_cel_generate_peer_str_snapshot (struct ast_channel_snapshot *chan, struct ast_bridge *bridge)
 
static int test_cel_init_cb (struct ast_test_info *info, struct ast_test *test)
 
static int test_cel_peer_strings_match (const char *str1, const char *str2)
 Check two peer strings for equality.
 
static void test_sub (struct ast_event *event)
 
static int unload_module (void)
 

Variables

static struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_LOAD_ORDER , .description = "CEL unit tests" , .key = ASTERISK_GPL_KEY , .buildopt_sum = AST_BUILDOPT_SUM, .load = load_module, .unload = unload_module, .load_pri = AST_MODPRI_DEFAULT, .support_level = AST_MODULE_SUPPORT_CORE, }
 
static const struct ast_module_infoast_module_info = &__mod_info
 
static struct ao2_containercel_expected_events = NULL
 
static struct ao2_containercel_received_events = NULL
 
static struct ast_cel_general_configcel_test_config
 The CEL config used for CEL unit tests.
 
int do_mid_test_sync = 0
 Flag used to trigger a mid-test synchronization, access controlled by mid_test_sync_lock.
 
ast_mutex_t mid_test_sync_lock
 Lock used for synchronizing test execution stages with received events.
 
static struct ast_cel_general_configsaved_config
 A placeholder for Asterisk's 'real' CEL configuration.
 
ast_mutex_t sync_lock
 Lock used with sync_out for checking the end of test execution.
 
ast_cond_t sync_out
 Condition used for checking the end of test execution.
 
static struct ast_channel_tech test_cel_chan_tech
 A channel technology used for the unit tests.
 
static struct timespec to_sleep = {1, 0}
 A 1 second sleep.
 

Detailed Description

CEL unit tests.

Author
Kinsey Moore kmoor.nosp@m.e@di.nosp@m.gium..nosp@m.com

Definition in file test_cel.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 196 of file test_cel.c.

◆ ANSWER_CHANNEL

#define ANSWER_CHANNEL (   chan)
Value:
do { \
EMULATE_APP_DATA(chan, 1, "Answer", ""); \
ANSWER_NO_APP(chan); \
} while (0)

Definition at line 262 of file test_cel.c.

262 { \
263 EMULATE_APP_DATA(chan, 1, "Answer", ""); \
264 ANSWER_NO_APP(chan); \
265 } while (0)

◆ ANSWER_NO_APP

#define ANSWER_NO_APP (   chan)
Value:
do { \
ast_setstate(chan, AST_STATE_UP); \
APPEND_EVENT(chan, AST_CEL_ANSWER, NULL, NULL); \
} while (0)
@ AST_CEL_ANSWER
A ringing phone is answered.
Definition cel.h:51
@ AST_STATE_UP
#define NULL
Definition resample.c:96

Definition at line 267 of file test_cel.c.

267 { \
268 ast_setstate(chan, AST_STATE_UP); \
269 APPEND_EVENT(chan, AST_CEL_ANSWER, NULL, NULL); \
270 } while (0)

◆ APPEND_DUMMY_EVENT

#define APPEND_DUMMY_EVENT ( )
Value:
do { \
if (append_dummy_event()) { \
return AST_TEST_FAIL; \
} \
} while (0)
@ AST_TEST_FAIL
Definition test.h:196

Definition at line 111 of file test_cel.c.

111 { \
112 if (append_dummy_event()) { \
113 return AST_TEST_FAIL; \
114 } \
115 } while (0)

◆ APPEND_EVENT

#define APPEND_EVENT (   chan,
  ev_type,
  userevent,
  extra 
)
Value:
do { \
if (append_expected_event(chan, ev_type, userevent, extra, NULL)) { \
return AST_TEST_FAIL; \
} \
} while (0)
static int append_expected_event(struct ast_channel *chan, enum ast_cel_event_type type, const char *userdefevname, struct ast_json *extra, const char *peer)
Definition test_cel.c:1772

Definition at line 93 of file test_cel.c.

93 { \
94 if (append_expected_event(chan, ev_type, userevent, extra, NULL)) { \
95 return AST_TEST_FAIL; \
96 } \
97 } while (0)

◆ APPEND_EVENT_PEER

#define APPEND_EVENT_PEER (   chan,
  ev_type,
  userevent,
  extra,
  peer 
)
Value:
do { \
if (append_expected_event(chan, ev_type, userevent, extra, peer)) { \
return AST_TEST_FAIL; \
} \
} while (0)

Definition at line 99 of file test_cel.c.

99 { \
100 if (append_expected_event(chan, ev_type, userevent, extra, peer)) { \
101 return AST_TEST_FAIL; \
102 } \
103 } while (0)

◆ APPEND_EVENT_SNAPSHOT

#define APPEND_EVENT_SNAPSHOT (   snapshot,
  ev_type,
  userevent,
  extra,
  peer 
)
Value:
do { \
if (append_expected_event_snapshot(snapshot, ev_type, userevent, extra, peer)) { \
return AST_TEST_FAIL; \
} \
} while (0)
static int append_expected_event_snapshot(struct ast_channel_snapshot *snapshot, enum ast_cel_event_type type, const char *userdefevname, struct ast_json *extra, const char *peer)
Definition test_cel.c:1756

Definition at line 105 of file test_cel.c.

105 { \
106 if (append_expected_event_snapshot(snapshot, ev_type, userevent, extra, peer)) { \
107 return AST_TEST_FAIL; \
108 } \
109 } while (0)

◆ ATTENDEDTRANSFER_BRIDGE

#define ATTENDEDTRANSFER_BRIDGE (   channel1,
  bridge1,
  channel2,
  bridge2,
  channel3,
  channel4 
)

Definition at line 180 of file test_cel.c.

180 { \
181 RAII_VAR(struct ast_json *, extra, NULL, ast_json_unref); \
182 extra = ast_json_pack("{s: s, s: s, s: s, s: s, s: s, s: s, s: s, s: s}", \
183 "bridge1_id", bridge1->uniqueid, \
184 "channel2_name", ast_channel_name(channel2), \
185 "channel2_uniqueid", ast_channel_uniqueid(channel2), \
186 "bridge2_id", bridge2->uniqueid, \
187 "transferee_channel_name", ast_channel_name(channel4), \
188 "transferee_channel_uniqueid", ast_channel_uniqueid(channel4), \
189 "transfer_target_channel_name", ast_channel_name(channel3), \
190 "transfer_target_channel_uniqueid", ast_channel_uniqueid(channel3)); \
191 ast_test_validate(test, extra != NULL); \
192 APPEND_EVENT(channel1, AST_CEL_ATTENDEDTRANSFER, NULL, extra); \
193 } while (0)
@ AST_CEL_ATTENDEDTRANSFER
a transfer occurs
Definition cel.h:67
const char * ast_channel_name(const struct ast_channel *chan)
const char * ast_channel_uniqueid(const struct ast_channel *chan)
void ast_json_unref(struct ast_json *value)
Decrease refcount on value. If refcount reaches zero, value is freed.
Definition json.c:73
struct ast_json * ast_json_pack(char const *format,...)
Helper for creating complex JSON values.
Definition json.c:612
Abstract JSON element (object, array, string, int, ...).

◆ BLINDTRANSFER_EVENT

#define BLINDTRANSFER_EVENT (   channel,
  bridge,
  extension,
  context 
)

Definition at line 168 of file test_cel.c.

168 { \
169 RAII_VAR(struct ast_json *, extra, NULL, ast_json_unref); \
170 extra = ast_json_pack("{s: s, s: s, s: s, s: s, s: s}", \
171 "extension", extension, \
172 "context", context, \
173 "bridge_id", bridge->uniqueid, \
174 "transferee_channel_name", "N/A", \
175 "transferee_channel_uniqueid", "N/A"); \
176 ast_test_validate(test, extra != NULL); \
177 APPEND_EVENT(channel, AST_CEL_BLINDTRANSFER, NULL, extra); \
178 } while (0)
@ AST_CEL_BLINDTRANSFER
a transfer occurs
Definition cel.h:65
structure to hold extensions

◆ 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 199 of file test_cel.c.

◆ BRIDGE_ENTER

#define BRIDGE_ENTER (   channel,
  bridge 
)

Definition at line 147 of file test_cel.c.

147 { \
148 ast_test_validate(test, !ast_bridge_impart(bridge, channel, NULL, NULL, AST_BRIDGE_IMPART_CHAN_DEPARTABLE)); \
149 do_sleep(); \
150 BRIDGE_ENTER_EVENT(channel, bridge); \
151 mid_test_sync(); \
152 } while (0)
int ast_bridge_impart(struct ast_bridge *bridge, struct ast_channel *chan, struct ast_channel *swap, struct ast_bridge_features *features, enum ast_bridge_impart_flags flags) attribute_warn_unused_result
Impart a channel to a bridge (non-blocking)
Definition bridge.c:1947
@ AST_BRIDGE_IMPART_CHAN_DEPARTABLE
Definition bridge.h:592

◆ BRIDGE_ENTER_EVENT

#define BRIDGE_ENTER_EVENT (   channel,
  bridge 
)

Definition at line 154 of file test_cel.c.

154 { \
155 RAII_VAR(struct ast_str *, peer_str, NULL, ast_free); \
156 peer_str = test_cel_generate_peer_str(channel, bridge); \
157 ast_test_validate(test, peer_str != NULL); \
158 BRIDGE_ENTER_EVENT_PEER(channel, bridge, ast_str_buffer(peer_str)); \
159 } while (0)
#define ast_free(a)
Definition astmm.h:180
char *attribute_pure ast_str_buffer(const struct ast_str *buf)
Returns the string buffer within the ast_str buf.
Definition strings.h:761
Support for dynamic strings.
Definition strings.h:623
static struct ast_str * test_cel_generate_peer_str(struct ast_channel *chan, struct ast_bridge *bridge)
Definition test_cel.c:364

◆ BRIDGE_ENTER_EVENT_PEER

#define BRIDGE_ENTER_EVENT_PEER (   channel,
  bridge,
  peer 
)

Definition at line 161 of file test_cel.c.

161 { \
162 RAII_VAR(struct ast_json *, extra, NULL, ast_json_unref); \
163 extra = ast_json_pack("{s: s, s: s}", "bridge_id", bridge->uniqueid, "bridge_technology", bridge->technology->name); \
164 ast_test_validate(test, extra != NULL); \
165 APPEND_EVENT_PEER(channel, AST_CEL_BRIDGE_ENTER, NULL, extra, peer); \
166 } while (0)
@ AST_CEL_BRIDGE_ENTER
channel enters a bridge
Definition cel.h:57

◆ BRIDGE_EXIT

#define BRIDGE_EXIT (   channel,
  bridge 
)
Value:
do { \
ast_test_validate(test, !ast_bridge_depart(channel)); \
BRIDGE_EXIT_EVENT(channel, bridge); \
mid_test_sync(); \
} while (0)
int ast_bridge_depart(struct ast_channel *chan)
Depart a channel from a bridge.
Definition bridge.c:1975

Definition at line 117 of file test_cel.c.

117 { \
118 ast_test_validate(test, !ast_bridge_depart(channel)); \
119 BRIDGE_EXIT_EVENT(channel, bridge); \
120 mid_test_sync(); \
121 } while (0)

◆ BRIDGE_EXIT_EVENT

#define BRIDGE_EXIT_EVENT (   channel,
  bridge 
)

Definition at line 123 of file test_cel.c.

123 { \
124 RAII_VAR(struct ast_str *, peer_str, NULL, ast_free); \
125 peer_str = test_cel_generate_peer_str(channel, bridge); \
126 ast_test_validate(test, peer_str != NULL); \
127 BRIDGE_EXIT_EVENT_PEER(channel, bridge, ast_str_buffer(peer_str)); \
128 } while (0)

◆ BRIDGE_EXIT_EVENT_PEER

#define BRIDGE_EXIT_EVENT_PEER (   channel,
  bridge,
  peer 
)

Definition at line 130 of file test_cel.c.

130 { \
131 RAII_VAR(struct ast_json *, extra, NULL, ast_json_unref); \
132 extra = ast_json_pack("{s: s, s: s}", "bridge_id", bridge->uniqueid, "bridge_technology", bridge->technology->name); \
133 ast_test_validate(test, extra != NULL); \
134 APPEND_EVENT_PEER(channel, AST_CEL_BRIDGE_EXIT, NULL, extra, peer); \
135 } while (0)
@ AST_CEL_BRIDGE_EXIT
channel exits a bridge
Definition cel.h:59

◆ BRIDGE_EXIT_SNAPSHOT

#define BRIDGE_EXIT_SNAPSHOT (   channel,
  bridge 
)

Definition at line 137 of file test_cel.c.

137 { \
138 RAII_VAR(struct ast_json *, extra, NULL, ast_json_unref); \
139 RAII_VAR(struct ast_str *, peer_str, NULL, ast_free); \
140 peer_str = test_cel_generate_peer_str_snapshot(channel, bridge); \
141 ast_test_validate(test, peer_str != NULL); \
142 extra = ast_json_pack("{s: s, s: s}", "bridge_id", bridge->uniqueid, "bridge_technology", bridge->technology->name); \
143 ast_test_validate(test, extra != NULL); \
144 APPEND_EVENT_SNAPSHOT(channel, AST_CEL_BRIDGE_EXIT, NULL, extra, ast_str_buffer(peer_str)); \
145 } while (0)
static struct ast_str * test_cel_generate_peer_str_snapshot(struct ast_channel_snapshot *chan, struct ast_bridge *bridge)
Definition test_cel.c:351

◆ CHANNEL_TECH_NAME

#define CHANNEL_TECH_NAME   "CELTestChannel"

Definition at line 56 of file test_cel.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 202 of file test_cel.c.

◆ CREATE_ALICE_CHANNEL

#define CREATE_ALICE_CHANNEL (   channel_var,
  caller_id 
)

Create a test_cel_chan_tech for Alice.

Definition at line 221 of file test_cel.c.

221 { \
222 (channel_var) = ast_channel_alloc(0, AST_STATE_DOWN, (caller_id)->id.number.str, (caller_id)->id.name.str, "100", "100", "default", NULL, NULL, 0, CHANNEL_TECH_NAME "/Alice"); \
223 SET_FORMATS((channel_var));\
224 APPEND_EVENT(channel_var, AST_CEL_CHANNEL_START, NULL, NULL); \
225 ast_channel_unlock((channel_var)); \
226 } while (0)
@ AST_CEL_CHANNEL_START
channel birth
Definition cel.h:45
#define ast_channel_alloc(needqueue, state, cid_num, cid_name, acctcode, exten, context, assignedids, requestor, amaflag,...)
Create a channel structure.
Definition channel.h:1299
@ AST_STATE_DOWN
static const char name[]
Definition format_mp3.c:68
#define CHANNEL_TECH_NAME
Definition test_cel.c:56

◆ CREATE_BOB_CHANNEL

#define CREATE_BOB_CHANNEL (   channel_var,
  caller_id 
)

Create a test_cel_chan_tech for Bob.

Definition at line 229 of file test_cel.c.

229 { \
230 (channel_var) = ast_channel_alloc(0, AST_STATE_DOWN, (caller_id)->id.number.str, (caller_id)->id.name.str, "200", "200", "default", NULL, NULL, 0, CHANNEL_TECH_NAME "/Bob"); \
231 SET_FORMATS((channel_var));\
232 APPEND_EVENT(channel_var, AST_CEL_CHANNEL_START, NULL, NULL); \
233 ast_channel_unlock((channel_var)); \
234 } while (0)

◆ CREATE_CHARLIE_CHANNEL

#define CREATE_CHARLIE_CHANNEL (   channel_var,
  caller_id 
)

Create a test_cel_chan_tech for Charlie.

Definition at line 237 of file test_cel.c.

237 { \
238 (channel_var) = ast_channel_alloc(0, AST_STATE_DOWN, (caller_id)->id.number.str, (caller_id)->id.name.str, "300", "300", "default", NULL, NULL, 0, CHANNEL_TECH_NAME "/Charlie"); \
239 SET_FORMATS((channel_var));\
240 APPEND_EVENT(channel_var, AST_CEL_CHANNEL_START, NULL, NULL); \
241 ast_channel_unlock((channel_var)); \
242 } while (0)

◆ CREATE_DAVID_CHANNEL

#define CREATE_DAVID_CHANNEL (   channel_var,
  caller_id 
)

Create a test_cel_chan_tech for David.

Definition at line 245 of file test_cel.c.

245 { \
246 (channel_var) = ast_channel_alloc(0, AST_STATE_DOWN, (caller_id)->id.number.str, (caller_id)->id.name.str, "400", "400", "default", NULL, NULL, 0, CHANNEL_TECH_NAME "/David"); \
247 SET_FORMATS((channel_var));\
248 APPEND_EVENT(channel_var, AST_CEL_CHANNEL_START, NULL, NULL); \
249 ast_channel_unlock((channel_var)); \
250 } while (0)

◆ DAVID_CALLERID

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

David's Caller ID.

Definition at line 205 of file test_cel.c.

◆ EMULATE_APP_DATA

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

Emulate a channel entering into an application.

Definition at line 253 of file test_cel.c.

253 { \
254 if ((priority) > 0) { \
255 ast_channel_priority_set((channel), (priority)); \
256 } \
257 ast_channel_appl_set((channel), (application)); \
258 ast_channel_data_set((channel), (data)); \
259 ast_channel_publish_snapshot((channel)); \
260 } while (0)
static int priority

◆ EMULATE_DIAL

#define EMULATE_DIAL (   channel,
  dialstring 
)

Definition at line 745 of file test_cel.c.

745 { \
746 EMULATE_APP_DATA(channel, 1, "Dial", dialstring); \
748 return AST_TEST_FAIL; \
749 } \
750 } while (0)
@ AST_CEL_APP_START
an app starts
Definition cel.h:53

◆ HANGUP_CHANNEL

#define HANGUP_CHANNEL (   channel,
  cause,
  dialstatus 
)

Hang up a test channel safely.

Definition at line 273 of file test_cel.c.

273 { \
274 ast_channel_hangupcause_set((channel), (cause)); \
275 ao2_ref(channel, +1); \
276 ast_hangup((channel)); \
277 HANGUP_EVENT(channel, cause, dialstatus); \
278 APPEND_EVENT(channel, AST_CEL_CHANNEL_END, NULL, NULL); \
280 ao2_cleanup(channel); \
281 channel = NULL; \
282 } while (0)
@ AST_CEL_CHANNEL_END
channel end
Definition cel.h:47
struct ast_channel_snapshot * ast_channel_snapshot_get_latest(const char *uniqueid)
Obtain the latest ast_channel_snapshot from the Stasis Message Bus API cache. This is an ao2 object,...

◆ HANGUP_EVENT

#define HANGUP_EVENT (   channel,
  cause,
  dialstatus 
)

Definition at line 284 of file test_cel.c.

284 { \
285 RAII_VAR(struct ast_json *, extra, NULL, ast_json_unref); \
286 extra = ast_json_pack("{s: i, s: s, s: s}", \
287 "hangupcause", cause, \
288 "hangupsource", "", \
289 "dialstatus", dialstatus); \
290 ast_test_validate(test, extra != NULL); \
291 APPEND_EVENT(channel, AST_CEL_HANGUP, NULL, extra); \
292 } while (0)
@ AST_CEL_HANGUP
hangup terminates connection
Definition cel.h:49

◆ SET_FORMATS

#define SET_FORMATS (   chan)

Set ulaw format on channel.

Definition at line 208 of file test_cel.c.

208 {\
209 struct ast_format_cap *caps;\
211 ast_format_cap_append(caps, ast_format_ulaw, 0);\
212 ast_channel_nativeformats_set((chan), caps);\
213 ast_channel_set_writeformat((chan), ast_format_ulaw);\
214 ast_channel_set_rawwriteformat((chan), ast_format_ulaw);\
215 ast_channel_set_readformat((chan), ast_format_ulaw);\
216 ast_channel_set_rawreadformat((chan), ast_format_ulaw);\
217 ao2_ref(caps, -1);\
218} while (0)
struct ast_format * ast_format_ulaw
Built-in cached ulaw format.
@ AST_FORMAT_CAP_FLAG_DEFAULT
Definition format_cap.h:38
#define ast_format_cap_alloc(flags)
Allocate a new ast_format_cap structure.
Definition format_cap.h:49
Format capabilities structure, holds formats + preference order + etc.
Definition format_cap.c:54

◆ START_DIALED

#define START_DIALED (   caller,
  callee 
)     START_DIALED_FULL(caller, callee, "200", "Bob")

Definition at line 752 of file test_cel.c.

◆ START_DIALED_FULL

#define START_DIALED_FULL (   caller,
  callee,
  number,
  name 
)

Definition at line 755 of file test_cel.c.

755 { \
756 callee = ast_channel_alloc(0, AST_STATE_DOWN, NULL, NULL, number, NULL, NULL, NULL, caller, 0, CHANNEL_TECH_NAME "/" name); \
757 SET_FORMATS(callee);\
758 ast_channel_unlock(callee); \
760 return AST_TEST_FAIL; \
761 } \
762 ast_set_flag(ast_channel_flags(callee), AST_FLAG_OUTGOING); \
763 EMULATE_APP_DATA(callee, 0, "AppDial", "(Outgoing Line)"); \
764 ast_channel_publish_dial(caller, callee, name, NULL); \
765 } while (0)
struct ast_flags * ast_channel_flags(struct ast_channel *chan)
@ AST_FLAG_OUTGOING
Definition channel.h:1019
Number structure.

◆ TEST_BACKEND_NAME

#define TEST_BACKEND_NAME   "CEL Test Logging"

Definition at line 58 of file test_cel.c.

◆ TEST_CATEGORY

#define TEST_CATEGORY   "/main/cel/"

Definition at line 54 of file test_cel.c.

Function Documentation

◆ __reg_module()

static void __reg_module ( void  )
static

Definition at line 2231 of file test_cel.c.

◆ __test_cel_generate_peer_str()

static struct ast_str * __test_cel_generate_peer_str ( struct ast_channel_snapshot chan,
struct ast_bridge_snapshot bridge 
)
static

Definition at line 314 of file test_cel.c.

315{
316 struct ast_str *peer_str = ast_str_create(32);
317 struct ao2_iterator i;
318 char *current_chan = NULL;
319
320 if (!peer_str) {
321 return NULL;
322 }
323
324 for (i = ao2_iterator_init(bridge->channels, 0);
325 (current_chan = ao2_iterator_next(&i));
326 ao2_cleanup(current_chan)) {
327 RAII_VAR(struct ast_channel_snapshot *, current_snapshot,
328 NULL,
330
331 /* Don't add the channel for which this message is being generated */
332 if (!strcmp(current_chan, chan->base->uniqueid)) {
333 continue;
334 }
335
336 current_snapshot = ast_channel_snapshot_get_latest(current_chan);
337 if (!current_snapshot) {
338 continue;
339 }
340
341 ast_str_append(&peer_str, 0, "%s,", current_snapshot->base->name);
342 }
344
345 /* Rip off the trailing comma */
346 ast_str_truncate(peer_str, -1);
347
348 return peer_str;
349}
#define ao2_iterator_next(iter)
Definition astobj2.h:1911
#define ao2_cleanup(obj)
Definition astobj2.h:1934
struct ao2_iterator ao2_iterator_init(struct ao2_container *c, int flags) attribute_warn_unused_result
Create an iterator for a container.
void ao2_iterator_destroy(struct ao2_iterator *iter)
Destroy a container iterator.
char * ast_str_truncate(struct ast_str *buf, ssize_t len)
Truncates the enclosed string to the given length.
Definition strings.h:786
int ast_str_append(struct ast_str **buf, ssize_t max_len, const char *fmt,...)
Append to a thread local dynamic string.
Definition strings.h:1139
#define ast_str_create(init_len)
Create a malloc'ed dynamic length string.
Definition strings.h:659
When we need to walk through a container, we use an ao2_iterator to keep track of the current positio...
Definition astobj2.h:1821
struct ao2_container * channels
Definition bridge.h:335
const ast_string_field uniqueid
Structure representing a snapshot of channel state.
struct ast_channel_snapshot_base * base
#define RAII_VAR(vartype, varname, initval, dtor)
Declare a variable that will call a destructor function when it goes out of scope.
Definition utils.h:978

References ao2_cleanup, ao2_iterator_destroy(), ao2_iterator_init(), ao2_iterator_next, ast_channel_snapshot_get_latest(), ast_str_append(), ast_str_create, ast_str_truncate(), ast_channel_snapshot::base, ast_bridge_snapshot::channels, NULL, RAII_VAR, and ast_channel_snapshot_base::uniqueid.

Referenced by test_cel_generate_peer_str_snapshot().

◆ __unreg_module()

static void __unreg_module ( void  )
static

Definition at line 2231 of file test_cel.c.

◆ ao2_dup_event()

static struct ast_event * ao2_dup_event ( const struct ast_event event)
static

Definition at line 1689 of file test_cel.c.

1690{
1691 struct ast_event *event_dup;
1692 uint16_t event_len;
1693
1695
1696 event_dup = ao2_alloc(event_len, NULL);
1697 if (!event_dup) {
1698 return NULL;
1699 }
1700
1701 memcpy(event_dup, event, event_len);
1702
1703 return event_dup;
1704}
#define ao2_alloc(data_size, destructor_fn)
Definition astobj2.h:409
size_t ast_event_get_size(const struct ast_event *event)
Get the size of an event.
Definition event.c:229
An event.
Definition event.c:81
uint16_t event_len
Definition event.c:85

References ao2_alloc, ast_event_get_size(), ast_event::event_len, and NULL.

Referenced by append_event(), and test_sub().

◆ append_event()

static int append_event ( struct ast_event ev)
static

Definition at line 1729 of file test_cel.c.

1730{
1731 RAII_VAR(struct ast_event *, ao2_ev, NULL, ao2_cleanup);
1732 ao2_ev = ao2_dup_event(ev);
1733 if (!ao2_ev) {
1734 return -1;
1735 }
1736
1738 return 0;
1739}
#define ao2_link(container, obj)
Add an object to a container.
Definition astobj2.h:1532
static struct ast_event * ao2_dup_event(const struct ast_event *event)
Definition test_cel.c:1689
static struct ao2_container * cel_expected_events
Definition test_cel.c:1687

References ao2_cleanup, ao2_dup_event(), ao2_link, cel_expected_events, NULL, and RAII_VAR.

Referenced by append_expected_event_snapshot().

◆ append_expected_event()

static int append_expected_event ( struct ast_channel chan,
enum ast_cel_event_type  type,
const char *  userdefevname,
struct ast_json extra,
const char *  peer 
)
static

Definition at line 1772 of file test_cel.c.

1778{
1779 RAII_VAR(struct ast_channel_snapshot *, snapshot, NULL, ao2_cleanup);
1780 ast_channel_lock(chan);
1781 snapshot = ast_channel_snapshot_create(chan);
1782 ast_channel_unlock(chan);
1783 if (!snapshot) {
1784 return -1;
1785 }
1786
1787 return append_expected_event_snapshot(snapshot, type, userdefevname, extra, peer);
1788}
static const char type[]
#define ast_channel_lock(chan)
Definition channel.h:2982
#define ast_channel_unlock(chan)
Definition channel.h:2983
struct ast_channel_snapshot * ast_channel_snapshot_create(struct ast_channel *chan)
Generate a snapshot of the channel state. This is an ao2 object, so ao2_cleanup() to deallocate.

References ao2_cleanup, append_expected_event_snapshot(), ast_channel_lock, ast_channel_snapshot_create(), ast_channel_unlock, NULL, RAII_VAR, and type.

◆ append_expected_event_snapshot()

static int append_expected_event_snapshot ( struct ast_channel_snapshot snapshot,
enum ast_cel_event_type  type,
const char *  userdefevname,
struct ast_json extra,
const char *  peer 
)
static

Definition at line 1756 of file test_cel.c.

1762{
1763 RAII_VAR(struct ast_event *, ev, NULL, ast_free);
1764 ev = ast_cel_create_event(snapshot, type, userdefevname, extra, peer);
1765 if (!ev) {
1766 return -1;
1767 }
1768
1769 return append_event(ev);
1770}
struct ast_event * ast_cel_create_event(struct ast_channel_snapshot *snapshot, enum ast_cel_event_type event_type, const char *userdefevname, struct ast_json *extra, const char *peer_str)
Allocate and populate a CEL event structure.
Definition cel.c:540
static int append_event(struct ast_event *ev)
Definition test_cel.c:1729

References append_event(), ast_cel_create_event(), ast_free, NULL, RAII_VAR, and type.

Referenced by append_expected_event().

◆ AST_MODULE_SELF_SYM()

struct ast_module * AST_MODULE_SELF_SYM ( void  )

Definition at line 2231 of file test_cel.c.

◆ AST_TEST_DEFINE() [1/22]

AST_TEST_DEFINE ( test_cel_attended_transfer_bridges_merge  )

Definition at line 1387 of file test_cel.c.

1388{
1389 RAII_VAR(struct ast_channel *, chan_alice, NULL, safe_channel_release);
1390 RAII_VAR(struct ast_channel *, chan_bob, NULL, safe_channel_release);
1391 RAII_VAR(struct ast_channel *, chan_charlie, NULL, safe_channel_release);
1392 RAII_VAR(struct ast_channel *, chan_david, NULL, safe_channel_release);
1393 RAII_VAR(struct ast_bridge *, bridge1, NULL, safe_bridge_destroy);
1394 RAII_VAR(struct ast_bridge *, bridge2, NULL, safe_bridge_destroy);
1395 struct ast_party_caller alice_caller = ALICE_CALLERID;
1396 struct ast_party_caller bob_caller = BOB_CALLERID;
1397 struct ast_party_caller charlie_caller = CHARLIE_CALLERID;
1398 struct ast_party_caller david_caller = ALICE_CALLERID;
1399
1400 switch (cmd) {
1401 case TEST_INIT:
1402 info->name = __func__;
1403 info->category = TEST_CATEGORY;
1404 info->summary = "Test attended transfers between two pairs of"
1405 " bridged parties that results in a bridge merge";
1406 info->description =
1407 "This test creates four channels, places each pair"
1408 " in a bridge, and then attended transfers the bridges"
1409 " together causing a bridge merge.";
1410 return AST_TEST_NOT_RUN;
1411 case TEST_EXECUTE:
1412 break;
1413 }
1414 /* Create first set of bridged parties */
1417 "test_cel", "test_cel_atxfer_bridges_merge_1", NULL);
1418 ast_test_validate(test, bridge1 != NULL);
1419
1420 CREATE_ALICE_CHANNEL(chan_alice, &alice_caller);
1421 CREATE_BOB_CHANNEL(chan_bob, &bob_caller);
1422 ANSWER_NO_APP(chan_alice);
1423 ANSWER_NO_APP(chan_bob);
1424
1425 BRIDGE_ENTER(chan_bob, bridge1);
1426 BRIDGE_ENTER(chan_alice, bridge1);
1427
1428 /* Create second set of bridged parties */
1431 "test_cel", "test_cel_atxfer_bridges_merge_2", NULL);
1432 ast_test_validate(test, bridge2 != NULL);
1433
1434 CREATE_DAVID_CHANNEL(chan_david, &david_caller);
1435 CREATE_CHARLIE_CHANNEL(chan_charlie, &charlie_caller);
1436 ANSWER_NO_APP(chan_david);
1437 ANSWER_NO_APP(chan_charlie);
1438
1439 BRIDGE_ENTER(chan_charlie, bridge2);
1440
1441 BRIDGE_ENTER(chan_david, bridge2);
1442
1443 /* Perform attended transfer */
1444 if (ast_bridge_transfer_attended(chan_alice, chan_david)) {
1445 ast_test_status_update(test, "Attended transfer failed!\n");
1446 return AST_TEST_FAIL;
1447 }
1448 do_sleep();
1449 BRIDGE_EXIT_EVENT_PEER(chan_charlie, bridge2, "CELTestChannel/David");
1450 BRIDGE_ENTER_EVENT_PEER(chan_charlie, bridge1, "CELTestChannel/Bob,CELTestChannel/Alice");
1451 BRIDGE_EXIT_EVENT(chan_david, bridge2);
1452 BRIDGE_EXIT_EVENT(chan_alice, bridge1);
1453
1454 ATTENDEDTRANSFER_BRIDGE(chan_alice, bridge1, chan_david, bridge2, chan_charlie, chan_bob);
1455
1456 do_sleep();
1457 BRIDGE_EXIT(chan_bob, bridge1);
1458 BRIDGE_EXIT(chan_charlie, bridge1);
1459
1460 HANGUP_CHANNEL(chan_alice, AST_CAUSE_NORMAL, "");
1461 do_sleep();
1462 HANGUP_CHANNEL(chan_bob, AST_CAUSE_NORMAL, "");
1463 do_sleep();
1464 HANGUP_CHANNEL(chan_david, AST_CAUSE_NORMAL, "");
1465 do_sleep();
1466 HANGUP_CHANNEL(chan_charlie, AST_CAUSE_NORMAL, "");
1467
1468 return AST_TEST_PASS;
1469}
struct ast_bridge * ast_bridge_base_new(uint32_t capabilities, unsigned int flags, const char *creator, const char *name, const char *id)
Create a new base class bridge.
Definition bridge.c:999
@ AST_BRIDGE_CAPABILITY_MULTIMIX
Definition bridge.h:98
@ AST_BRIDGE_CAPABILITY_NATIVE
Definition bridge.h:94
@ AST_BRIDGE_CAPABILITY_1TO1MIX
Definition bridge.h:96
enum ast_transfer_result ast_bridge_transfer_attended(struct ast_channel *to_transferee, struct ast_channel *to_transfer_target)
Attended transfer.
Definition bridge.c:4756
@ AST_BRIDGE_FLAG_SWAP_INHIBIT_FROM
@ AST_BRIDGE_FLAG_TRANSFER_PROHIBITED
@ AST_BRIDGE_FLAG_SMART
#define AST_CAUSE_NORMAL
Definition causes.h:151
Structure that contains information about a bridge.
Definition bridge.h:353
Main Channel structure associated with a channel.
Caller Party information.
Definition channel.h:420
@ TEST_INIT
Definition test.h:200
@ TEST_EXECUTE
Definition test.h:201
#define ast_test_status_update(a, b, c...)
Definition test.h:129
@ AST_TEST_PASS
Definition test.h:195
@ AST_TEST_NOT_RUN
Definition test.h:194
#define CREATE_ALICE_CHANNEL(channel_var, caller_id)
Create a test_cel_chan_tech for Alice.
Definition test_cel.c:221
#define BRIDGE_EXIT_EVENT(channel, bridge)
Definition test_cel.c:123
#define CREATE_BOB_CHANNEL(channel_var, caller_id)
Create a test_cel_chan_tech for Bob.
Definition test_cel.c:229
static void safe_bridge_destroy(struct ast_bridge *bridge)
Definition test_cel.c:385
#define BOB_CALLERID
Bob's Caller ID.
Definition test_cel.c:199
static void do_sleep(void)
Definition test_cel.c:87
#define BRIDGE_EXIT(channel, bridge)
Definition test_cel.c:117
#define ALICE_CALLERID
Alice's Caller ID.
Definition test_cel.c:196
#define BRIDGE_ENTER(channel, bridge)
Definition test_cel.c:147
#define BRIDGE_EXIT_EVENT_PEER(channel, bridge, peer)
Definition test_cel.c:130
static void safe_channel_release(struct ast_channel *chan)
Definition test_cel.c:377
#define CREATE_DAVID_CHANNEL(channel_var, caller_id)
Create a test_cel_chan_tech for David.
Definition test_cel.c:245
#define BRIDGE_ENTER_EVENT_PEER(channel, bridge, peer)
Definition test_cel.c:161
#define ATTENDEDTRANSFER_BRIDGE(channel1, bridge1, channel2, bridge2, channel3, channel4)
Definition test_cel.c:180
#define CREATE_CHARLIE_CHANNEL(channel_var, caller_id)
Create a test_cel_chan_tech for Charlie.
Definition test_cel.c:237
#define ANSWER_NO_APP(chan)
Definition test_cel.c:267
#define HANGUP_CHANNEL(channel, cause, dialstatus)
Hang up a test channel safely.
Definition test_cel.c:273
#define TEST_CATEGORY
Definition test_cel.c:54
#define CHARLIE_CALLERID
Charlie's Caller ID.
Definition test_cel.c:202

References ALICE_CALLERID, ANSWER_NO_APP, ast_bridge_base_new(), AST_BRIDGE_CAPABILITY_1TO1MIX, AST_BRIDGE_CAPABILITY_MULTIMIX, AST_BRIDGE_CAPABILITY_NATIVE, AST_BRIDGE_FLAG_SMART, AST_BRIDGE_FLAG_SWAP_INHIBIT_FROM, AST_BRIDGE_FLAG_TRANSFER_PROHIBITED, ast_bridge_transfer_attended(), AST_CAUSE_NORMAL, AST_TEST_FAIL, AST_TEST_NOT_RUN, AST_TEST_PASS, ast_test_status_update, ATTENDEDTRANSFER_BRIDGE, BOB_CALLERID, BRIDGE_ENTER, BRIDGE_ENTER_EVENT_PEER, BRIDGE_EXIT, BRIDGE_EXIT_EVENT, BRIDGE_EXIT_EVENT_PEER, CHARLIE_CALLERID, CREATE_ALICE_CHANNEL, CREATE_BOB_CHANNEL, CREATE_CHARLIE_CHANNEL, CREATE_DAVID_CHANNEL, do_sleep(), HANGUP_CHANNEL, NULL, RAII_VAR, safe_bridge_destroy(), safe_channel_release(), TEST_CATEGORY, TEST_EXECUTE, and TEST_INIT.

◆ AST_TEST_DEFINE() [2/22]

AST_TEST_DEFINE ( test_cel_blind_transfer  )

Definition at line 1240 of file test_cel.c.

1241{
1242 RAII_VAR(struct ast_channel *, chan_alice, NULL, safe_channel_release);
1243 RAII_VAR(struct ast_channel *, chan_bob, NULL, safe_channel_release);
1244 RAII_VAR(struct ast_bridge *, bridge, NULL, safe_bridge_destroy);
1245 RAII_VAR(struct ast_blind_transfer_message *, transfer_msg, NULL, ao2_cleanup);
1246 struct ast_party_caller alice_caller = ALICE_CALLERID;
1247 struct ast_party_caller bob_caller = BOB_CALLERID;
1248
1249 switch (cmd) {
1250 case TEST_INIT:
1251 info->name = __func__;
1252 info->category = TEST_CATEGORY;
1253 info->summary = "Test blind transfers to an extension";
1254 info->description =
1255 "This test creates two channels, bridges them, and then"
1256 " blind transfers the bridge to an extension.";
1257 return AST_TEST_NOT_RUN;
1258 case TEST_EXECUTE:
1259 break;
1260 }
1261 bridge = ast_bridge_basic_new();
1262 ast_test_validate(test, bridge != NULL);
1263
1264 CREATE_ALICE_CHANNEL(chan_alice, &alice_caller);
1265 CREATE_BOB_CHANNEL(chan_bob, &bob_caller);
1266
1267 ANSWER_NO_APP(chan_alice);
1268 ANSWER_NO_APP(chan_bob);
1269
1270 BRIDGE_ENTER(chan_bob, bridge);
1271 BRIDGE_ENTER(chan_alice, bridge);
1272
1273 ast_bridge_lock(bridge);
1274 transfer_msg = ast_blind_transfer_message_create(1, chan_alice,
1275 "transfer_extension", "transfer_context");
1276 if (!transfer_msg) {
1277 ast_bridge_unlock(bridge);
1278 ast_test_status_update(test, "Failed to create transfer Stasis message\n");
1279 return AST_TEST_FAIL;
1280 }
1281 transfer_msg->bridge = ast_bridge_snapshot_create(bridge);
1282 if (!transfer_msg->bridge) {
1283 ast_bridge_unlock(bridge);
1284 ast_test_status_update(test, "Failed to create bridge snapshot\n");
1285 return AST_TEST_FAIL;
1286 }
1287 ast_bridge_unlock(bridge);
1288 transfer_msg->result = AST_BRIDGE_TRANSFER_SUCCESS;
1290 BLINDTRANSFER_EVENT(chan_alice, bridge, "transfer_extension", "transfer_context");
1291
1292 BRIDGE_EXIT(chan_alice, bridge);
1293 BRIDGE_EXIT(chan_bob, bridge);
1294
1295 HANGUP_CHANNEL(chan_alice, AST_CAUSE_NORMAL, "");
1296 do_sleep();
1297 HANGUP_CHANNEL(chan_bob, AST_CAUSE_NORMAL, "");
1298
1299 return AST_TEST_PASS;
1300}
#define ast_bridge_unlock(bridge)
Unlock the bridge.
Definition bridge.h:485
@ AST_BRIDGE_TRANSFER_SUCCESS
Definition bridge.h:1104
#define ast_bridge_lock(bridge)
Lock the bridge.
Definition bridge.h:474
struct ast_bridge * ast_bridge_basic_new(void)
Create a new basic class bridge.
void ast_bridge_publish_blind_transfer(struct ast_blind_transfer_message *transfer_message)
Publish a blind transfer event.
struct ast_bridge_snapshot * ast_bridge_snapshot_create(struct ast_bridge *bridge)
Generate a snapshot of the bridge state. This is an ao2 object, so ao2_cleanup() to deallocate.
struct ast_blind_transfer_message * ast_blind_transfer_message_create(int is_external, struct ast_channel *transferer, const char *exten, const char *context)
Create a blind transfer message to be published.
Message published during a blind transfer.
#define BLINDTRANSFER_EVENT(channel, bridge, extension, context)
Definition test_cel.c:168

References ALICE_CALLERID, ANSWER_NO_APP, ao2_cleanup, ast_blind_transfer_message_create(), ast_bridge_basic_new(), ast_bridge_lock, ast_bridge_publish_blind_transfer(), ast_bridge_snapshot_create(), AST_BRIDGE_TRANSFER_SUCCESS, ast_bridge_unlock, AST_CAUSE_NORMAL, AST_TEST_FAIL, AST_TEST_NOT_RUN, AST_TEST_PASS, ast_test_status_update, BLINDTRANSFER_EVENT, BOB_CALLERID, BRIDGE_ENTER, BRIDGE_EXIT, CREATE_ALICE_CHANNEL, CREATE_BOB_CHANNEL, do_sleep(), HANGUP_CHANNEL, NULL, RAII_VAR, safe_bridge_destroy(), safe_channel_release(), TEST_CATEGORY, TEST_EXECUTE, and TEST_INIT.

◆ AST_TEST_DEFINE() [3/22]

AST_TEST_DEFINE ( test_cel_channel_creation  )

Definition at line 393 of file test_cel.c.

394{
396 struct ast_party_caller caller = ALICE_CALLERID;
397
398 switch (cmd) {
399 case TEST_INIT:
400 info->name = __func__;
401 info->category = TEST_CATEGORY;
402 info->summary = "Test the CEL records created when a channel is created";
403 info->description =
404 "Test the CEL records created when a channel is created";
405 return AST_TEST_NOT_RUN;
406 case TEST_EXECUTE:
407 break;
408 }
409
410 CREATE_ALICE_CHANNEL(chan, (&caller));
411
413
414 return AST_TEST_PASS;
415}

References ALICE_CALLERID, AST_CAUSE_NORMAL, AST_TEST_NOT_RUN, AST_TEST_PASS, CREATE_ALICE_CHANNEL, HANGUP_CHANNEL, NULL, RAII_VAR, safe_channel_release(), TEST_CATEGORY, TEST_EXECUTE, and TEST_INIT.

◆ AST_TEST_DEFINE() [4/22]

AST_TEST_DEFINE ( test_cel_dial_answer_no_bridge  )

Definition at line 1026 of file test_cel.c.

1027{
1028 RAII_VAR(struct ast_channel *, chan_caller, NULL, safe_channel_release);
1029 RAII_VAR(struct ast_channel *, chan_callee, NULL, safe_channel_release);
1030 struct ast_party_caller caller = ALICE_CALLERID;
1031
1032 switch (cmd) {
1033 case TEST_INIT:
1034 info->name = __func__;
1035 info->category = TEST_CATEGORY;
1036 info->summary = "Test dialing, answering, and not going into a bridge.";
1037 info->description =
1038 "This is a weird one, but theoretically possible. You can perform\n"
1039 "a dial, then bounce both channels to different priorities and\n"
1040 "never have them enter a bridge together. Ew. This makes sure that\n"
1041 "when we answer, we get a CEL, it gets ended at that point, and\n"
1042 "that it gets finalized appropriately.";
1043 return AST_TEST_NOT_RUN;
1044 case TEST_EXECUTE:
1045 break;
1046 }
1047
1048 CREATE_ALICE_CHANNEL(chan_caller, &caller);
1049
1050 EMULATE_DIAL(chan_caller, CHANNEL_TECH_NAME "/Bob");
1051
1052 START_DIALED(chan_caller, chan_callee);
1053
1055 ast_channel_publish_dial(chan_caller, chan_callee, NULL, "ANSWER");
1056
1057 ANSWER_NO_APP(chan_caller);
1059 ANSWER_NO_APP(chan_callee);
1060
1061 EMULATE_APP_DATA(chan_caller, 2, "Wait", "1");
1062 EMULATE_APP_DATA(chan_callee, 1, "Wait", "1");
1063
1064 HANGUP_CHANNEL(chan_caller, AST_CAUSE_NORMAL, "ANSWER");
1065 HANGUP_CHANNEL(chan_callee, AST_CAUSE_NORMAL, "");
1066
1067 return AST_TEST_PASS;
1068}
void ast_channel_state_set(struct ast_channel *chan, enum ast_channel_state)
@ AST_STATE_RINGING
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...
#define EMULATE_DIAL(channel, dialstring)
Definition test_cel.c:745
#define START_DIALED(caller, callee)
Definition test_cel.c:752
#define EMULATE_APP_DATA(channel, priority, application, data)
Emulate a channel entering into an application.
Definition test_cel.c:253
#define ast_clear_flag(p, flag)
Definition utils.h:77

References ALICE_CALLERID, ANSWER_NO_APP, AST_CAUSE_NORMAL, ast_channel_flags(), ast_channel_publish_dial(), ast_channel_state_set(), ast_clear_flag, AST_FLAG_OUTGOING, AST_STATE_RINGING, AST_TEST_NOT_RUN, AST_TEST_PASS, CHANNEL_TECH_NAME, CREATE_ALICE_CHANNEL, EMULATE_APP_DATA, EMULATE_DIAL, HANGUP_CHANNEL, NULL, RAII_VAR, safe_channel_release(), START_DIALED, TEST_CATEGORY, TEST_EXECUTE, and TEST_INIT.

◆ AST_TEST_DEFINE() [5/22]

AST_TEST_DEFINE ( test_cel_dial_answer_twoparty_bridge_a  )

Definition at line 1070 of file test_cel.c.

1071{
1072 RAII_VAR(struct ast_channel *, chan_caller, NULL, safe_channel_release);
1073 RAII_VAR(struct ast_channel *, chan_callee, NULL, safe_channel_release);
1074 RAII_VAR(struct ast_bridge *, bridge, NULL, safe_bridge_destroy);
1075 struct ast_party_caller caller = ALICE_CALLERID;
1076
1077 switch (cmd) {
1078 case TEST_INIT:
1079 info->name = __func__;
1080 info->category = TEST_CATEGORY;
1081 info->summary = "Test dialing, answering, and going into a 2-party bridge";
1082 info->description =
1083 "The most 'basic' of scenarios";
1084 return AST_TEST_NOT_RUN;
1085 case TEST_EXECUTE:
1086 break;
1087 }
1088 bridge = ast_bridge_basic_new();
1089 ast_test_validate(test, bridge != NULL);
1090
1091 CREATE_ALICE_CHANNEL(chan_caller, &caller);
1092
1093 EMULATE_DIAL(chan_caller, CHANNEL_TECH_NAME "/Bob");
1094
1095 START_DIALED(chan_caller, chan_callee);
1096
1098 ast_channel_publish_dial(chan_caller, chan_callee, NULL, "ANSWER");
1099
1100 ANSWER_NO_APP(chan_caller);
1101 ANSWER_NO_APP(chan_callee);
1102
1103 do_sleep();
1104
1105 BRIDGE_ENTER(chan_caller, bridge);
1106 BRIDGE_ENTER(chan_callee, bridge);
1107
1108 BRIDGE_EXIT(chan_caller, bridge);
1109 BRIDGE_EXIT(chan_callee, bridge);
1110
1111 HANGUP_CHANNEL(chan_caller, AST_CAUSE_NORMAL, "ANSWER");
1112 HANGUP_CHANNEL(chan_callee, AST_CAUSE_NORMAL, "");
1113
1114 return AST_TEST_PASS;
1115}

References ALICE_CALLERID, ANSWER_NO_APP, ast_bridge_basic_new(), AST_CAUSE_NORMAL, ast_channel_publish_dial(), ast_channel_state_set(), AST_STATE_RINGING, AST_TEST_NOT_RUN, AST_TEST_PASS, BRIDGE_ENTER, BRIDGE_EXIT, CHANNEL_TECH_NAME, CREATE_ALICE_CHANNEL, do_sleep(), EMULATE_DIAL, HANGUP_CHANNEL, NULL, RAII_VAR, safe_bridge_destroy(), safe_channel_release(), START_DIALED, TEST_CATEGORY, TEST_EXECUTE, and TEST_INIT.

◆ AST_TEST_DEFINE() [6/22]

AST_TEST_DEFINE ( test_cel_dial_answer_twoparty_bridge_b  )

Definition at line 1117 of file test_cel.c.

1118{
1119 RAII_VAR(struct ast_channel *, chan_caller, NULL, safe_channel_release);
1120 RAII_VAR(struct ast_channel *, chan_callee, NULL, safe_channel_release);
1121 RAII_VAR(struct ast_bridge *, bridge, NULL, safe_bridge_destroy);
1122 struct ast_party_caller caller = ALICE_CALLERID;
1123
1124 switch (cmd) {
1125 case TEST_INIT:
1126 info->name = __func__;
1127 info->category = TEST_CATEGORY;
1128 info->summary = "Test dialing, answering, and going into a 2-party bridge";
1129 info->description =
1130 "The most 'basic' of scenarios";
1131 return AST_TEST_NOT_RUN;
1132 case TEST_EXECUTE:
1133 break;
1134 }
1135 bridge = ast_bridge_basic_new();
1136 ast_test_validate(test, bridge != NULL);
1137
1138 CREATE_ALICE_CHANNEL(chan_caller, &caller);
1139
1140 EMULATE_DIAL(chan_caller, CHANNEL_TECH_NAME "/Bob");
1141
1142 START_DIALED(chan_caller, chan_callee);
1143
1145 ast_channel_publish_dial(chan_caller, chan_callee, NULL, "ANSWER");
1146
1147 ANSWER_NO_APP(chan_caller);
1148 ANSWER_NO_APP(chan_callee);
1149
1150 do_sleep();
1151 BRIDGE_ENTER(chan_callee, bridge);
1152 BRIDGE_ENTER(chan_caller, bridge);
1153
1154 BRIDGE_EXIT(chan_caller, bridge);
1155 BRIDGE_EXIT(chan_callee, bridge);
1156
1157 HANGUP_CHANNEL(chan_caller, AST_CAUSE_NORMAL, "ANSWER");
1158 HANGUP_CHANNEL(chan_callee, AST_CAUSE_NORMAL, "");
1159
1160 return AST_TEST_PASS;
1161}

References ALICE_CALLERID, ANSWER_NO_APP, ast_bridge_basic_new(), AST_CAUSE_NORMAL, ast_channel_publish_dial(), ast_channel_state_set(), AST_STATE_RINGING, AST_TEST_NOT_RUN, AST_TEST_PASS, BRIDGE_ENTER, BRIDGE_EXIT, CHANNEL_TECH_NAME, CREATE_ALICE_CHANNEL, do_sleep(), EMULATE_DIAL, HANGUP_CHANNEL, NULL, RAII_VAR, safe_bridge_destroy(), safe_channel_release(), START_DIALED, TEST_CATEGORY, TEST_EXECUTE, and TEST_INIT.

◆ AST_TEST_DEFINE() [7/22]

AST_TEST_DEFINE ( test_cel_dial_busy  )

Definition at line 836 of file test_cel.c.

837{
838 RAII_VAR(struct ast_channel *, chan_caller, NULL, safe_channel_release);
839 RAII_VAR(struct ast_channel *, chan_callee, NULL, safe_channel_release);
840 struct ast_party_caller caller = ALICE_CALLERID;
841
842 switch (cmd) {
843 case TEST_INIT:
844 info->name = __func__;
845 info->category = TEST_CATEGORY;
846 info->summary = "Test CEL for a dial that results in a busy";
847 info->description =
848 "Test CEL records for a channel that\n"
849 "performs a dial operation to an endpoint that's busy";
850 return AST_TEST_NOT_RUN;
851 case TEST_EXECUTE:
852 break;
853 }
854
855 CREATE_ALICE_CHANNEL(chan_caller, &caller);
856
857 EMULATE_DIAL(chan_caller, CHANNEL_TECH_NAME "/Bob");
858
859 START_DIALED(chan_caller, chan_callee);
860
862 ast_channel_publish_dial(chan_caller, chan_callee, NULL, "BUSY");
863
864 HANGUP_CHANNEL(chan_caller, AST_CAUSE_BUSY, "BUSY");
865 HANGUP_CHANNEL(chan_callee, AST_CAUSE_BUSY, "");
866
867 return AST_TEST_PASS;
868}
#define AST_CAUSE_BUSY
Definition causes.h:149

References ALICE_CALLERID, AST_CAUSE_BUSY, ast_channel_publish_dial(), ast_channel_state_set(), AST_STATE_RINGING, AST_TEST_NOT_RUN, AST_TEST_PASS, CHANNEL_TECH_NAME, CREATE_ALICE_CHANNEL, EMULATE_DIAL, HANGUP_CHANNEL, NULL, RAII_VAR, safe_channel_release(), START_DIALED, TEST_CATEGORY, TEST_EXECUTE, and TEST_INIT.

◆ AST_TEST_DEFINE() [8/22]

AST_TEST_DEFINE ( test_cel_dial_caller_cancel  )

Definition at line 938 of file test_cel.c.

939{
940 RAII_VAR(struct ast_channel *, chan_caller, NULL, safe_channel_release);
941 RAII_VAR(struct ast_channel *, chan_callee, NULL, safe_channel_release);
942 struct ast_party_caller caller = ALICE_CALLERID;
943
944 switch (cmd) {
945 case TEST_INIT:
946 info->name = __func__;
947 info->category = TEST_CATEGORY;
948 info->summary = "Test CEL for a dial where the caller cancels";
949 info->description =
950 "Test CEL records for a channel that\n"
951 "performs a dial operation to an endpoint but then decides\n"
952 "to hang up, cancelling the dial";
953 return AST_TEST_NOT_RUN;
954 case TEST_EXECUTE:
955 break;
956 }
957
958 CREATE_ALICE_CHANNEL(chan_caller, &caller);
959
960 EMULATE_DIAL(chan_caller, CHANNEL_TECH_NAME "/Bob");
961
962 START_DIALED(chan_caller, chan_callee);
963
965 ast_channel_publish_dial(chan_caller, chan_callee, NULL, "CANCEL");
966
967 HANGUP_CHANNEL(chan_callee, AST_CAUSE_NORMAL, "");
968 HANGUP_CHANNEL(chan_caller, AST_CAUSE_NORMAL, "CANCEL");
969
970 return AST_TEST_PASS;
971}

References ALICE_CALLERID, AST_CAUSE_NORMAL, ast_channel_publish_dial(), ast_channel_state_set(), AST_STATE_RINGING, AST_TEST_NOT_RUN, AST_TEST_PASS, CHANNEL_TECH_NAME, CREATE_ALICE_CHANNEL, EMULATE_DIAL, HANGUP_CHANNEL, NULL, RAII_VAR, safe_channel_release(), START_DIALED, TEST_CATEGORY, TEST_EXECUTE, and TEST_INIT.

◆ AST_TEST_DEFINE() [9/22]

AST_TEST_DEFINE ( test_cel_dial_congestion  )

Definition at line 870 of file test_cel.c.

871{
872 RAII_VAR(struct ast_channel *, chan_caller, NULL, safe_channel_release);
873 RAII_VAR(struct ast_channel *, chan_callee, NULL, safe_channel_release);
874 struct ast_party_caller caller = ALICE_CALLERID;
875
876 switch (cmd) {
877 case TEST_INIT:
878 info->name = __func__;
879 info->category = TEST_CATEGORY;
880 info->summary = "Test CEL for a dial that results in congestion";
881 info->description =
882 "Test CEL records for a channel that\n"
883 "performs a dial operation to an endpoint that's congested";
884 return AST_TEST_NOT_RUN;
885 case TEST_EXECUTE:
886 break;
887 }
888
889 CREATE_ALICE_CHANNEL(chan_caller, &caller);
890
891 EMULATE_DIAL(chan_caller, CHANNEL_TECH_NAME "/Bob");
892
893 START_DIALED(chan_caller, chan_callee);
894
896 ast_channel_publish_dial(chan_caller, chan_callee, NULL, "CONGESTION");
897
898 HANGUP_CHANNEL(chan_caller, AST_CAUSE_CONGESTION, "CONGESTION");
899 HANGUP_CHANNEL(chan_callee, AST_CAUSE_CONGESTION, "");
900
901 return AST_TEST_PASS;
902}
#define AST_CAUSE_CONGESTION
Definition causes.h:153

References ALICE_CALLERID, AST_CAUSE_CONGESTION, ast_channel_publish_dial(), ast_channel_state_set(), AST_STATE_RINGING, AST_TEST_NOT_RUN, AST_TEST_PASS, CHANNEL_TECH_NAME, CREATE_ALICE_CHANNEL, EMULATE_DIAL, HANGUP_CHANNEL, NULL, RAII_VAR, safe_channel_release(), START_DIALED, TEST_CATEGORY, TEST_EXECUTE, and TEST_INIT.

◆ AST_TEST_DEFINE() [10/22]

AST_TEST_DEFINE ( test_cel_dial_parallel_failed  )

Definition at line 973 of file test_cel.c.

974{
975 RAII_VAR(struct ast_channel *, chan_caller, NULL, safe_channel_release);
976 RAII_VAR(struct ast_channel *, chan_bob, NULL, safe_channel_release);
977 RAII_VAR(struct ast_channel *, chan_charlie, NULL, safe_channel_release);
978 RAII_VAR(struct ast_channel *, chan_david, NULL, safe_channel_release);
979 struct ast_party_caller caller = ALICE_CALLERID;
980
981 switch (cmd) {
982 case TEST_INIT:
983 info->name = __func__;
984 info->category = TEST_CATEGORY;
985 info->summary = "Test a parallel dial where all channels fail to answer";
986 info->description =
987 "This tests dialing three parties: Bob, Charlie, David. Charlie\n"
988 "returns BUSY; David returns CONGESTION; Bob fails to answer and\n"
989 "Alice hangs up. Three records are created for Alice as a result.";
990 return AST_TEST_NOT_RUN;
991 case TEST_EXECUTE:
992 break;
993 }
994
995 CREATE_ALICE_CHANNEL(chan_caller, &caller);
996
997 /* Channel enters Dial app */
998 EMULATE_DIAL(chan_caller, CHANNEL_TECH_NAME "/Bob&" CHANNEL_TECH_NAME "/Charlie&" CHANNEL_TECH_NAME "/David");
999
1000 /* Outbound channels are created */
1001 START_DIALED_FULL(chan_caller, chan_bob, "200", "Bob");
1002 START_DIALED_FULL(chan_caller, chan_charlie, "300", "Charlie");
1003 START_DIALED_FULL(chan_caller, chan_david, "400", "David");
1004
1005 /* Dial starts */
1007
1008 /* Charlie is busy */
1009 ast_channel_publish_dial(chan_caller, chan_charlie, NULL, "BUSY");
1010 HANGUP_CHANNEL(chan_charlie, AST_CAUSE_BUSY, "");
1011
1012 /* David is congested */
1013 ast_channel_publish_dial(chan_caller, chan_david, NULL, "CONGESTION");
1014 HANGUP_CHANNEL(chan_david, AST_CAUSE_CONGESTION, "");
1015
1016 /* Bob is canceled */
1017 ast_channel_publish_dial(chan_caller, chan_bob, NULL, "CANCEL");
1018 HANGUP_CHANNEL(chan_bob, AST_CAUSE_NORMAL, "");
1019
1020 /* Alice hangs up */
1021 HANGUP_CHANNEL(chan_caller, AST_CAUSE_NORMAL, "BUSY");
1022
1023 return AST_TEST_PASS;
1024}
#define START_DIALED_FULL(caller, callee, number, name)
Definition test_cel.c:755

References ALICE_CALLERID, AST_CAUSE_BUSY, AST_CAUSE_CONGESTION, AST_CAUSE_NORMAL, ast_channel_publish_dial(), ast_channel_state_set(), AST_STATE_RINGING, AST_TEST_NOT_RUN, AST_TEST_PASS, CHANNEL_TECH_NAME, CREATE_ALICE_CHANNEL, EMULATE_DIAL, HANGUP_CHANNEL, NULL, RAII_VAR, safe_channel_release(), START_DIALED_FULL, TEST_CATEGORY, TEST_EXECUTE, and TEST_INIT.

◆ AST_TEST_DEFINE() [11/22]

AST_TEST_DEFINE ( test_cel_dial_pickup  )

Definition at line 1561 of file test_cel.c.

1562{
1563 RAII_VAR(struct ast_channel *, chan_caller, NULL, safe_channel_release);
1564 RAII_VAR(struct ast_channel *, chan_callee, NULL, safe_channel_release);
1565 RAII_VAR(struct ast_channel *, chan_charlie, NULL, safe_channel_release);
1566 struct ast_party_caller caller = ALICE_CALLERID;
1567 struct ast_party_caller charlie_caller = CHARLIE_CALLERID;
1568
1569 switch (cmd) {
1570 case TEST_INIT:
1571 info->name = __func__;
1572 info->category = TEST_CATEGORY;
1573 info->summary = "Test call pickup";
1574 info->description =
1575 "Test CEL records for a call that is\n"
1576 "inbound to Asterisk, executes some dialplan, and\n"
1577 "is picked up.";
1578 return AST_TEST_NOT_RUN;
1579 case TEST_EXECUTE:
1580 break;
1581 }
1582
1583 CREATE_ALICE_CHANNEL(chan_caller, &caller);
1584
1585 EMULATE_DIAL(chan_caller, CHANNEL_TECH_NAME "/Bob");
1586
1587 START_DIALED(chan_caller, chan_callee);
1588
1590
1591 CREATE_CHARLIE_CHANNEL(chan_charlie, &charlie_caller);
1592
1593 {
1594 RAII_VAR(struct ast_json *, extra, NULL, ast_json_unref);
1595 SCOPED_CHANNELLOCK(lock, chan_callee);
1596
1597 extra = ast_json_pack("{s: s, s: s}", "pickup_channel", ast_channel_name(chan_charlie),
1598 "pickup_channel_uniqueid", ast_channel_uniqueid(chan_charlie));
1599 ast_test_validate(test, extra != NULL);
1600
1601 APPEND_EVENT(chan_callee, AST_CEL_PICKUP, NULL, extra);
1602 ast_test_validate(test, !ast_do_pickup(chan_charlie, chan_callee));
1603 }
1604
1605 /* Hang up the masqueraded zombie */
1606 HANGUP_CHANNEL(chan_charlie, AST_CAUSE_NORMAL, "");
1607
1608 ast_channel_publish_dial(chan_caller, chan_callee, NULL, "ANSWER");
1609
1610 HANGUP_CHANNEL(chan_caller, AST_CAUSE_NORMAL, "ANSWER");
1611 HANGUP_CHANNEL(chan_callee, AST_CAUSE_NORMAL, "");
1612
1613 return AST_TEST_PASS;
1614}
ast_mutex_t lock
Definition app_sla.c:337
@ AST_CEL_PICKUP
a directed pickup was performed on this channel
Definition cel.h:73
#define SCOPED_CHANNELLOCK(varname, chan)
scoped lock specialization for channels.
Definition lock.h:626
int ast_do_pickup(struct ast_channel *chan, struct ast_channel *target)
Pickup a call target.
Definition pickup.c:304
#define APPEND_EVENT(chan, ev_type, userevent, extra)
Definition test_cel.c:93

References ALICE_CALLERID, APPEND_EVENT, AST_CAUSE_NORMAL, AST_CEL_PICKUP, ast_channel_name(), ast_channel_publish_dial(), ast_channel_state_set(), ast_channel_uniqueid(), ast_do_pickup(), ast_json_pack(), ast_json_unref(), AST_STATE_RINGING, AST_TEST_NOT_RUN, AST_TEST_PASS, CHANNEL_TECH_NAME, CHARLIE_CALLERID, CREATE_ALICE_CHANNEL, CREATE_CHARLIE_CHANNEL, EMULATE_DIAL, HANGUP_CHANNEL, lock, NULL, RAII_VAR, safe_channel_release(), SCOPED_CHANNELLOCK, START_DIALED, TEST_CATEGORY, TEST_EXECUTE, and TEST_INIT.

◆ AST_TEST_DEFINE() [12/22]

AST_TEST_DEFINE ( test_cel_dial_unanswered  )

Definition at line 767 of file test_cel.c.

768{
769 RAII_VAR(struct ast_channel *, chan_caller, NULL, safe_channel_release);
770 RAII_VAR(struct ast_channel *, chan_callee, NULL, safe_channel_release);
771 struct ast_party_caller caller = ALICE_CALLERID;
772
773 switch (cmd) {
774 case TEST_INIT:
775 info->name = __func__;
776 info->category = TEST_CATEGORY;
777 info->summary = "Test CEL for a dial that isn't answered";
778 info->description =
779 "Test CEL records for a channel that\n"
780 "performs a dial operation that isn't answered";
781 return AST_TEST_NOT_RUN;
782 case TEST_EXECUTE:
783 break;
784 }
785
786 CREATE_ALICE_CHANNEL(chan_caller, &caller);
787
788 EMULATE_DIAL(chan_caller, CHANNEL_TECH_NAME "/Bob");
789
790 START_DIALED(chan_caller, chan_callee);
791
793 ast_channel_publish_dial(chan_caller, chan_callee, NULL, "NOANSWER");
794
795 HANGUP_CHANNEL(chan_caller, AST_CAUSE_NO_ANSWER, "NOANSWER");
796 HANGUP_CHANNEL(chan_callee, AST_CAUSE_NO_ANSWER, "");
797
798 return AST_TEST_PASS;
799}
#define AST_CAUSE_NO_ANSWER
Definition causes.h:109

References ALICE_CALLERID, AST_CAUSE_NO_ANSWER, ast_channel_publish_dial(), ast_channel_state_set(), AST_STATE_RINGING, AST_TEST_NOT_RUN, AST_TEST_PASS, CHANNEL_TECH_NAME, CREATE_ALICE_CHANNEL, EMULATE_DIAL, HANGUP_CHANNEL, NULL, RAII_VAR, safe_channel_release(), START_DIALED, TEST_CATEGORY, TEST_EXECUTE, and TEST_INIT.

◆ AST_TEST_DEFINE() [13/22]

AST_TEST_DEFINE ( test_cel_dial_unanswered_filter  )

Definition at line 801 of file test_cel.c.

802{
803 RAII_VAR(struct ast_channel *, chan_caller, NULL, safe_channel_release);
804 RAII_VAR(struct ast_channel *, chan_callee, NULL, safe_channel_release);
805 struct ast_party_caller caller = ALICE_CALLERID;
806
807 switch (cmd) {
808 case TEST_INIT:
809 info->name = __func__;
810 info->category = TEST_CATEGORY;
811 info->summary = "Test CEL for a dial that isn't answered";
812 info->description =
813 "Test CEL records for a channel that\n"
814 "performs a dial operation that isn't answered";
815 return AST_TEST_NOT_RUN;
816 case TEST_EXECUTE:
817 break;
818 }
819
820 CREATE_ALICE_CHANNEL(chan_caller, &caller);
821
822 EMULATE_DIAL(chan_caller, CHANNEL_TECH_NAME "/Bob");
823
824 START_DIALED(chan_caller, chan_callee);
825
827 ast_channel_publish_dial(chan_caller, chan_callee, NULL, "NOT A VALID DIAL STATUS");
828 ast_channel_publish_dial(chan_caller, chan_callee, NULL, "NOANSWER");
829
830 HANGUP_CHANNEL(chan_caller, AST_CAUSE_NO_ANSWER, "NOANSWER");
831 HANGUP_CHANNEL(chan_callee, AST_CAUSE_NO_ANSWER, "");
832
833 return AST_TEST_PASS;
834}

References ALICE_CALLERID, AST_CAUSE_NO_ANSWER, ast_channel_publish_dial(), ast_channel_state_set(), AST_STATE_RINGING, AST_TEST_NOT_RUN, AST_TEST_PASS, CHANNEL_TECH_NAME, CREATE_ALICE_CHANNEL, EMULATE_DIAL, HANGUP_CHANNEL, NULL, RAII_VAR, safe_channel_release(), START_DIALED, TEST_CATEGORY, TEST_EXECUTE, and TEST_INIT.

◆ AST_TEST_DEFINE() [14/22]

AST_TEST_DEFINE ( test_cel_dial_unavailable  )

Definition at line 904 of file test_cel.c.

905{
906 RAII_VAR(struct ast_channel *, chan_caller, NULL, safe_channel_release);
907 RAII_VAR(struct ast_channel *, chan_callee, NULL, safe_channel_release);
908 struct ast_party_caller caller = ALICE_CALLERID;
909
910 switch (cmd) {
911 case TEST_INIT:
912 info->name = __func__;
913 info->category = TEST_CATEGORY;
914 info->summary = "Test CEL for a dial that results in unavailable";
915 info->description =
916 "Test CEL records for a channel that\n"
917 "performs a dial operation to an endpoint that's unavailable";
918 return AST_TEST_NOT_RUN;
919 case TEST_EXECUTE:
920 break;
921 }
922
923 CREATE_ALICE_CHANNEL(chan_caller, &caller);
924
925 EMULATE_DIAL(chan_caller, CHANNEL_TECH_NAME "/Bob");
926
927 START_DIALED(chan_caller, chan_callee);
928
930 ast_channel_publish_dial(chan_caller, chan_callee, NULL, "CHANUNAVAIL");
931
932 HANGUP_CHANNEL(chan_caller, AST_CAUSE_NO_ROUTE_DESTINATION, "CHANUNAVAIL");
934
935 return AST_TEST_PASS;
936}
#define AST_CAUSE_NO_ROUTE_DESTINATION
Definition causes.h:100

References ALICE_CALLERID, AST_CAUSE_NO_ROUTE_DESTINATION, ast_channel_publish_dial(), ast_channel_state_set(), AST_STATE_RINGING, AST_TEST_NOT_RUN, AST_TEST_PASS, CHANNEL_TECH_NAME, CREATE_ALICE_CHANNEL, EMULATE_DIAL, HANGUP_CHANNEL, NULL, RAII_VAR, safe_channel_release(), START_DIALED, TEST_CATEGORY, TEST_EXECUTE, and TEST_INIT.

◆ AST_TEST_DEFINE() [15/22]

AST_TEST_DEFINE ( test_cel_local_optimize  )

Definition at line 1616 of file test_cel.c.

1617{
1618 RAII_VAR(struct ast_channel *, chan_alice, NULL, safe_channel_release);
1619 RAII_VAR(struct ast_channel *, chan_bob, NULL, safe_channel_release);
1620 struct ast_party_caller alice_caller = ALICE_CALLERID;
1621 struct ast_party_caller bob_caller = BOB_CALLERID;
1622 RAII_VAR(struct ast_multi_channel_blob *, mc_blob, NULL, ao2_cleanup);
1623 RAII_VAR(struct ast_channel_snapshot *, alice_snapshot, NULL, ao2_cleanup);
1624 RAII_VAR(struct ast_channel_snapshot *, bob_snapshot, NULL, ao2_cleanup);
1625 RAII_VAR(struct stasis_message *, local_opt_begin, NULL, ao2_cleanup);
1626 RAII_VAR(struct stasis_message *, local_opt_end, NULL, ao2_cleanup);
1627 RAII_VAR(struct ast_json *, extra, NULL, ast_json_unref);
1628
1629 switch (cmd) {
1630 case TEST_INIT:
1631 info->name = __func__;
1632 info->category = TEST_CATEGORY;
1633 info->summary = "Test local channel optimization record generation";
1634 info->description =
1635 "Test CEL records for two local channels being optimized\n"
1636 "out by sending a messages indicating local optimization\n"
1637 "begin and end";
1638 return AST_TEST_NOT_RUN;
1639 case TEST_EXECUTE:
1640 break;
1641 }
1642
1644 ast_test_validate(test, mc_blob != NULL);
1645
1646 CREATE_ALICE_CHANNEL(chan_alice, &alice_caller);
1647 CREATE_BOB_CHANNEL(chan_bob, &bob_caller);
1648
1649 ast_channel_lock(chan_alice);
1650 alice_snapshot = ast_channel_snapshot_create(chan_alice);
1651 ast_channel_unlock(chan_alice);
1652 ast_test_validate(test, alice_snapshot != NULL);
1653
1654 ast_channel_lock(chan_bob);
1655 bob_snapshot = ast_channel_snapshot_create(chan_bob);
1656 ast_channel_unlock(chan_bob);
1657 ast_test_validate(test, bob_snapshot != NULL);
1658
1659 ast_multi_channel_blob_add_channel(mc_blob, "1", alice_snapshot);
1660 ast_multi_channel_blob_add_channel(mc_blob, "2", bob_snapshot);
1661
1662 local_opt_begin = stasis_message_create(ast_local_optimization_begin_type(), mc_blob);
1663 ast_test_validate(test, local_opt_begin != NULL);
1664
1665 local_opt_end = stasis_message_create(ast_local_optimization_end_type(), mc_blob);
1666 ast_test_validate(test, local_opt_end != NULL);
1667
1668 stasis_publish(ast_channel_topic(chan_alice), local_opt_begin);
1669 stasis_publish(ast_channel_topic(chan_alice), local_opt_end);
1670
1671 extra = ast_json_pack("{s: s, s: s}", "local_two", bob_snapshot->base->name,
1672 "local_two_uniqueid", bob_snapshot->base->uniqueid);
1673 ast_test_validate(test, extra != NULL);
1674
1675 APPEND_EVENT_SNAPSHOT(alice_snapshot, AST_CEL_LOCAL_OPTIMIZE, NULL, extra, NULL);
1676
1677 HANGUP_CHANNEL(chan_alice, AST_CAUSE_NORMAL, "");
1678 HANGUP_CHANNEL(chan_bob, AST_CAUSE_NORMAL, "");
1679
1680 return AST_TEST_PASS;
1681}
@ AST_CEL_LOCAL_OPTIMIZE
A local channel optimization occurred, this marks the end.
Definition cel.h:77
struct stasis_topic * ast_channel_topic(struct ast_channel *chan)
A topic which publishes the events for a particular channel.
struct stasis_message_type * ast_local_optimization_end_type(void)
Message type for when a local channel optimization completes.
struct stasis_message_type * ast_local_optimization_begin_type(void)
Message type for when a local channel optimization begins.
struct ast_multi_channel_blob * ast_multi_channel_blob_create(struct ast_json *blob)
Create a ast_multi_channel_blob suitable for a stasis_message.
void ast_multi_channel_blob_add_channel(struct ast_multi_channel_blob *obj, const char *role, struct ast_channel_snapshot *snapshot)
Add a ast_channel_snapshot to a ast_multi_channel_blob object.
struct ast_json * ast_json_null(void)
Get the JSON null value.
Definition json.c:248
struct stasis_message * stasis_message_create(struct stasis_message_type *type, void *data)
Create a new message.
void stasis_publish(struct stasis_topic *topic, struct stasis_message *message)
Publish a message to a topic's subscribers.
Definition stasis.c:1578
A multi channel blob data structure for multi_channel_blob stasis messages.
#define APPEND_EVENT_SNAPSHOT(snapshot, ev_type, userevent, extra, peer)
Definition test_cel.c:105

References ALICE_CALLERID, ao2_cleanup, APPEND_EVENT_SNAPSHOT, AST_CAUSE_NORMAL, AST_CEL_LOCAL_OPTIMIZE, ast_channel_lock, ast_channel_snapshot_create(), ast_channel_topic(), ast_channel_unlock, ast_json_null(), ast_json_pack(), ast_json_unref(), ast_local_optimization_begin_type(), ast_local_optimization_end_type(), ast_multi_channel_blob_add_channel(), ast_multi_channel_blob_create(), AST_TEST_NOT_RUN, AST_TEST_PASS, BOB_CALLERID, CREATE_ALICE_CHANNEL, CREATE_BOB_CHANNEL, HANGUP_CHANNEL, NULL, RAII_VAR, safe_channel_release(), stasis_message_create(), stasis_publish(), TEST_CATEGORY, TEST_EXECUTE, and TEST_INIT.

◆ AST_TEST_DEFINE() [16/22]

AST_TEST_DEFINE ( test_cel_single_bridge  )

Definition at line 505 of file test_cel.c.

506{
508 RAII_VAR(struct ast_bridge *, bridge, NULL, safe_bridge_destroy);
509
510 struct ast_party_caller caller = ALICE_CALLERID;
511
512 switch (cmd) {
513 case TEST_INIT:
514 info->name = __func__;
515 info->category = TEST_CATEGORY;
516 info->summary = "Test CEL for a single party entering/leaving a bridge";
517 info->description =
518 "Test CEL records for a call that is\n"
519 "answered, enters a bridge, and leaves it.";
520 return AST_TEST_NOT_RUN;
521 case TEST_EXECUTE:
522 break;
523 }
524 bridge = ast_bridge_basic_new();
525 ast_test_validate(test, bridge != NULL);
526
527 CREATE_ALICE_CHANNEL(chan, &caller);
528
529 ANSWER_CHANNEL(chan);
530 EMULATE_APP_DATA(chan, 2, "Bridge", "");
531
532 do_sleep();
533 BRIDGE_ENTER(chan, bridge);
534
535 do_sleep();
536
537 BRIDGE_EXIT(chan, bridge);
538
540
541 return AST_TEST_PASS;
542}
#define ANSWER_CHANNEL(chan)
Definition test_cel.c:262

References ALICE_CALLERID, ANSWER_CHANNEL, ast_bridge_basic_new(), AST_CAUSE_NORMAL, AST_TEST_NOT_RUN, AST_TEST_PASS, BRIDGE_ENTER, BRIDGE_EXIT, CREATE_ALICE_CHANNEL, do_sleep(), EMULATE_APP_DATA, HANGUP_CHANNEL, NULL, RAII_VAR, safe_bridge_destroy(), safe_channel_release(), TEST_CATEGORY, TEST_EXECUTE, and TEST_INIT.

◆ AST_TEST_DEFINE() [17/22]

AST_TEST_DEFINE ( test_cel_single_bridge_continue  )

Definition at line 544 of file test_cel.c.

545{
547 RAII_VAR(struct ast_bridge *, bridge, NULL, safe_bridge_destroy);
548 struct ast_party_caller caller = ALICE_CALLERID;
549
550 switch (cmd) {
551 case TEST_INIT:
552 info->name = __func__;
553 info->category = TEST_CATEGORY;
554 info->summary = "Test CEL for a single party entering/leaving a bridge";
555 info->description =
556 "Test CEL records for a call that is\n"
557 "answered, enters a bridge, and leaves it.";
558 return AST_TEST_NOT_RUN;
559 case TEST_EXECUTE:
560 break;
561 }
562 bridge = ast_bridge_basic_new();
563 ast_test_validate(test, bridge != NULL);
564
565 CREATE_ALICE_CHANNEL(chan, &caller);
566
567 ANSWER_CHANNEL(chan);
568 EMULATE_APP_DATA(chan, 2, "Bridge", "");
569
570 do_sleep();
571 BRIDGE_ENTER(chan, bridge);
572
573 do_sleep();
574
575 BRIDGE_EXIT(chan, bridge);
576
577 EMULATE_APP_DATA(chan, 3, "Wait", "");
578
579 /* And then it hangs up */
581
582 return AST_TEST_PASS;
583}

References ALICE_CALLERID, ANSWER_CHANNEL, ast_bridge_basic_new(), AST_CAUSE_NORMAL, AST_TEST_NOT_RUN, AST_TEST_PASS, BRIDGE_ENTER, BRIDGE_EXIT, CREATE_ALICE_CHANNEL, do_sleep(), EMULATE_APP_DATA, HANGUP_CHANNEL, NULL, RAII_VAR, safe_bridge_destroy(), safe_channel_release(), TEST_CATEGORY, TEST_EXECUTE, and TEST_INIT.

◆ AST_TEST_DEFINE() [18/22]

AST_TEST_DEFINE ( test_cel_single_party  )

Definition at line 478 of file test_cel.c.

479{
481 struct ast_party_caller caller = ALICE_CALLERID;
482
483 switch (cmd) {
484 case TEST_INIT:
485 info->name = __func__;
486 info->category = TEST_CATEGORY;
487 info->summary = "Test CEL for a single party";
488 info->description =
489 "Test CEL records for a call that is\n"
490 "answered, but only involves a single channel";
491 return AST_TEST_NOT_RUN;
492 case TEST_EXECUTE:
493 break;
494 }
495 CREATE_ALICE_CHANNEL(chan, &caller);
496
497 ANSWER_CHANNEL(chan);
498 EMULATE_APP_DATA(chan, 2, "VoiceMailMain", "1");
499
501
502 return AST_TEST_PASS;
503}

References ALICE_CALLERID, ANSWER_CHANNEL, AST_CAUSE_NORMAL, AST_TEST_NOT_RUN, AST_TEST_PASS, CREATE_ALICE_CHANNEL, EMULATE_APP_DATA, HANGUP_CHANNEL, NULL, RAII_VAR, safe_channel_release(), TEST_CATEGORY, TEST_EXECUTE, and TEST_INIT.

◆ AST_TEST_DEFINE() [19/22]

AST_TEST_DEFINE ( test_cel_single_twoparty_bridge_a  )

Definition at line 585 of file test_cel.c.

586{
587 RAII_VAR(struct ast_channel *, chan_alice, NULL, safe_channel_release);
588 RAII_VAR(struct ast_channel *, chan_bob, NULL, safe_channel_release);
589 RAII_VAR(struct ast_bridge *, bridge, NULL, safe_bridge_destroy);
590 struct ast_party_caller caller_alice = ALICE_CALLERID;
591 struct ast_party_caller caller_bob = BOB_CALLERID;
592
593 switch (cmd) {
594 case TEST_INIT:
595 info->name = __func__;
596 info->category = TEST_CATEGORY;
597 info->summary = "Test CEL for a single party entering/leaving a bridge";
598 info->description =
599 "Test CEL records for a call that is\n"
600 "answered, enters a bridge, and leaves it. In this scenario, the\n"
601 "Party A should answer the bridge first.";
602 return AST_TEST_NOT_RUN;
603 case TEST_EXECUTE:
604 break;
605 }
606 bridge = ast_bridge_basic_new();
607 ast_test_validate(test, bridge != NULL);
608
609 CREATE_ALICE_CHANNEL(chan_alice, &caller_alice);
610
611 CREATE_BOB_CHANNEL(chan_bob, &caller_bob);
612
613 ANSWER_CHANNEL(chan_alice);
614 EMULATE_APP_DATA(chan_alice, 2, "Bridge", "");
615
616 BRIDGE_ENTER(chan_alice, bridge);
617 do_sleep();
618
619 ANSWER_CHANNEL(chan_bob);
620 EMULATE_APP_DATA(chan_bob, 2, "Bridge", "");
621
622 BRIDGE_ENTER(chan_bob, bridge);
623
624 BRIDGE_EXIT(chan_alice, bridge);
625 BRIDGE_EXIT(chan_bob, bridge);
626
627 HANGUP_CHANNEL(chan_alice, AST_CAUSE_NORMAL, "");
628 HANGUP_CHANNEL(chan_bob, AST_CAUSE_NORMAL, "");
629
630 return AST_TEST_PASS;
631}

References ALICE_CALLERID, ANSWER_CHANNEL, ast_bridge_basic_new(), AST_CAUSE_NORMAL, AST_TEST_NOT_RUN, AST_TEST_PASS, BOB_CALLERID, BRIDGE_ENTER, BRIDGE_EXIT, CREATE_ALICE_CHANNEL, CREATE_BOB_CHANNEL, do_sleep(), EMULATE_APP_DATA, HANGUP_CHANNEL, NULL, RAII_VAR, safe_bridge_destroy(), safe_channel_release(), TEST_CATEGORY, TEST_EXECUTE, and TEST_INIT.

◆ AST_TEST_DEFINE() [20/22]

AST_TEST_DEFINE ( test_cel_single_twoparty_bridge_b  )

Definition at line 633 of file test_cel.c.

634{
635 RAII_VAR(struct ast_channel *, chan_alice, NULL, safe_channel_release);
636 RAII_VAR(struct ast_channel *, chan_bob, NULL, safe_channel_release);
637 RAII_VAR(struct ast_bridge *, bridge, NULL, safe_bridge_destroy);
638 struct ast_party_caller caller_alice = ALICE_CALLERID;
639 struct ast_party_caller caller_bob = BOB_CALLERID;
640
641 switch (cmd) {
642 case TEST_INIT:
643 info->name = __func__;
644 info->category = TEST_CATEGORY;
645 info->summary = "Test CEL for a single party entering/leaving a bridge";
646 info->description =
647 "Test CEL records for a call that is\n"
648 "answered, enters a bridge, and leaves it. In this scenario, the\n"
649 "Party B should answer the bridge first.";
650 return AST_TEST_NOT_RUN;
651 case TEST_EXECUTE:
652 break;
653 }
654 bridge = ast_bridge_basic_new();
655 ast_test_validate(test, bridge != NULL);
656
657 CREATE_ALICE_CHANNEL(chan_alice, &caller_alice);
658
659 CREATE_BOB_CHANNEL(chan_bob, &caller_bob);
660
661 ANSWER_CHANNEL(chan_alice);
662 EMULATE_APP_DATA(chan_alice, 2, "Bridge", "");
663
664 ANSWER_CHANNEL(chan_bob);
665 EMULATE_APP_DATA(chan_bob, 2, "Bridge", "");
666 do_sleep();
667
668 BRIDGE_ENTER(chan_bob, bridge);
669
670 BRIDGE_ENTER(chan_alice, bridge);
671
672 BRIDGE_EXIT(chan_alice, bridge);
673 BRIDGE_EXIT(chan_bob, bridge);
674
675 HANGUP_CHANNEL(chan_alice, AST_CAUSE_NORMAL, "");
676 HANGUP_CHANNEL(chan_bob, AST_CAUSE_NORMAL, "");
677
678 return AST_TEST_PASS;
679}

References ALICE_CALLERID, ANSWER_CHANNEL, ast_bridge_basic_new(), AST_CAUSE_NORMAL, AST_TEST_NOT_RUN, AST_TEST_PASS, BOB_CALLERID, BRIDGE_ENTER, BRIDGE_EXIT, CREATE_ALICE_CHANNEL, CREATE_BOB_CHANNEL, do_sleep(), EMULATE_APP_DATA, HANGUP_CHANNEL, NULL, RAII_VAR, safe_bridge_destroy(), safe_channel_release(), TEST_CATEGORY, TEST_EXECUTE, and TEST_INIT.

◆ AST_TEST_DEFINE() [21/22]

AST_TEST_DEFINE ( test_cel_unanswered_inbound_call  )

Definition at line 417 of file test_cel.c.

418{
420 struct ast_party_caller caller = ALICE_CALLERID;
421
422 switch (cmd) {
423 case TEST_INIT:
424 info->name = __func__;
425 info->category = TEST_CATEGORY;
426 info->summary = "Test inbound unanswered calls";
427 info->description =
428 "Test CEL records for a call that is\n"
429 "inbound to Asterisk, executes some dialplan, but\n"
430 "is never answered.";
431 return AST_TEST_NOT_RUN;
432 case TEST_EXECUTE:
433 break;
434 }
435
436 CREATE_ALICE_CHANNEL(chan, &caller);
437
438 EMULATE_APP_DATA(chan, 1, "Wait", "1");
439
441
442 return AST_TEST_PASS;
443}

References ALICE_CALLERID, AST_CAUSE_NORMAL, AST_TEST_NOT_RUN, AST_TEST_PASS, CREATE_ALICE_CHANNEL, EMULATE_APP_DATA, HANGUP_CHANNEL, NULL, RAII_VAR, safe_channel_release(), TEST_CATEGORY, TEST_EXECUTE, and TEST_INIT.

◆ AST_TEST_DEFINE() [22/22]

AST_TEST_DEFINE ( test_cel_unanswered_outbound_call  )

Definition at line 445 of file test_cel.c.

446{
448 struct ast_party_caller caller = {
449 .id.name.str = "",
450 .id.name.valid = 1,
451 .id.number.str = "",
452 .id.number.valid = 1, };
453
454 switch (cmd) {
455 case TEST_INIT:
456 info->name = __func__;
457 info->category = TEST_CATEGORY;
458 info->summary = "Test outbound unanswered calls";
459 info->description =
460 "Test CEL records for a call that is\n"
461 "outbound to Asterisk but is never answered.";
462 return AST_TEST_NOT_RUN;
463 case TEST_EXECUTE:
464 break;
465 }
466
467 CREATE_ALICE_CHANNEL(chan, &caller);
468
469 ast_channel_exten_set(chan, "s");
470 ast_channel_context_set(chan, "default");
472 EMULATE_APP_DATA(chan, 0, "AppDial", "(Outgoing Line)");
474
475 return AST_TEST_PASS;
476}
void ast_channel_exten_set(struct ast_channel *chan, const char *value)
void ast_channel_context_set(struct ast_channel *chan, const char *value)
@ AST_FLAG_ORIGINATED
Definition channel.h:1059
struct ast_party_id id
Caller party ID.
Definition channel.h:422
struct ast_party_name name
Subscriber name.
Definition channel.h:342
char * str
Subscriber name (Malloced)
Definition channel.h:266
#define ast_set_flag(p, flag)
Definition utils.h:70

References AST_CAUSE_NORMAL, ast_channel_context_set(), ast_channel_exten_set(), ast_channel_flags(), AST_FLAG_ORIGINATED, ast_set_flag, AST_TEST_NOT_RUN, AST_TEST_PASS, CREATE_ALICE_CHANNEL, EMULATE_APP_DATA, HANGUP_CHANNEL, ast_party_caller::id, ast_party_id::name, NULL, RAII_VAR, safe_channel_release(), ast_party_name::str, TEST_CATEGORY, TEST_EXECUTE, and TEST_INIT.

◆ cel_verify_and_cleanup_cb()

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

Definition at line 2076 of file test_cel.c.

2077{
2078 RAII_VAR(struct ao2_container *, local_expected, cel_expected_events, ao2_cleanup);
2079 RAII_VAR(struct ao2_container *, local_received, cel_received_events, ao2_cleanup);
2082
2083 do_sleep();
2084
2085 /* stop the CEL event callback and clean up storage structures*/
2087
2088 /* cleaned up by RAII_VAR's */
2091
2092 /* check events */
2093 ast_test_validate(test, !check_events(test, local_expected, local_received));
2094
2095 /* Restore the real CEL config */
2099
2100 /* clean up the locks */
2104 return 0;
2105}
void ast_cel_set_config(struct ast_cel_general_config *config)
Set the current CEL configuration.
Definition cel.c:1771
int ast_cel_backend_unregister(const char *name)
Unregister a CEL backend.
Definition cel.c:1797
#define ast_cond_destroy(cond)
Definition lock.h:209
#define ast_mutex_destroy(a)
Definition lock.h:195
Generic container type.
ast_cond_t sync_out
Condition used for checking the end of test execution.
Definition test_cel.c:73
static struct ao2_container * cel_received_events
Definition test_cel.c:1684
ast_mutex_t mid_test_sync_lock
Lock used for synchronizing test execution stages with received events.
Definition test_cel.c:67
#define TEST_BACKEND_NAME
Definition test_cel.c:58
static int check_events(struct ast_test *test, struct ao2_container *local_expected, struct ao2_container *local_received)
Definition test_cel.c:2010
ast_mutex_t sync_lock
Lock used with sync_out for checking the end of test execution.
Definition test_cel.c:70
static struct ast_cel_general_config * saved_config
A placeholder for Asterisk's 'real' CEL configuration.
Definition test_cel.c:61
#define ast_assert(a)
Definition utils.h:776

References ao2_cleanup, ast_assert, ast_cel_backend_unregister(), ast_cel_set_config(), ast_cond_destroy, ast_mutex_destroy, cel_expected_events, cel_received_events, check_events(), do_sleep(), mid_test_sync_lock, NULL, RAII_VAR, saved_config, sync_lock, sync_out, and TEST_BACKEND_NAME.

Referenced by load_module().

◆ check_events()

static int check_events ( struct ast_test *  test,
struct ao2_container local_expected,
struct ao2_container local_received 
)
static

Definition at line 2010 of file test_cel.c.

2011{
2012 struct ao2_iterator received_it;
2013 struct ao2_iterator expected_it;
2014 RAII_VAR(struct ast_event *, rx_event, NULL, ao2_cleanup);
2015 RAII_VAR(struct ast_event *, ex_event, NULL, ao2_cleanup);
2016 int debug = 0;
2017
2018 if (ao2_container_count(local_expected) != ao2_container_count(local_received)) {
2019 ast_test_status_update(test, "Increasing verbosity since the number of expected events (%d)"
2020 " did not match number of received events (%d).\n",
2021 ao2_container_count(local_expected),
2022 ao2_container_count(local_received));
2023 debug = 1;
2024 }
2025
2026 received_it = ao2_iterator_init(local_received, 0);
2027 expected_it = ao2_iterator_init(local_expected, 0);
2028 rx_event = ao2_iterator_next(&received_it);
2029 ex_event = ao2_iterator_next(&expected_it);
2030 while (rx_event && ex_event) {
2031 if (!events_are_equal(test, rx_event, ex_event)) {
2032 ao2_iterator_destroy(&received_it);
2033 ao2_iterator_destroy(&expected_it);
2034 ast_test_status_update(test, "Received event:\n");
2035 dump_event(test, rx_event);
2036 ast_test_status_update(test, "Expected event:\n");
2037 dump_event(test, ex_event);
2038 return -1;
2039 }
2040 if (debug) {
2041 ast_test_status_update(test, "Compared events successfully%s\n",
2043 ? " (wildcard match)" : "");
2044 dump_event(test, rx_event);
2045 }
2046 ao2_cleanup(rx_event);
2047 ao2_cleanup(ex_event);
2048 rx_event = ao2_iterator_next(&received_it);
2049 ex_event = ao2_iterator_next(&expected_it);
2050 }
2051 ao2_iterator_destroy(&received_it);
2052 ao2_iterator_destroy(&expected_it);
2053
2054 if (rx_event) {
2055 ast_test_status_update(test, "Received event:\n");
2056 dump_event(test, rx_event);
2057 return -1;
2058 }
2059 if (ex_event) {
2060 ast_test_status_update(test, "Expected event:\n");
2061 dump_event(test, ex_event);
2062 return -1;
2063 }
2064 return 0;
2065}
int ao2_container_count(struct ao2_container *c)
Returns the number of elements in a container.
enum ast_event_type ast_event_get_type(const struct ast_event *event)
Get the type for an event.
Definition event.c:289
@ AST_EVENT_CUSTOM
Definition event_defs.h:36
static int debug
Global debug status.
Definition res_xmpp.c:570
static int dump_event(struct ast_test *test, struct ast_event *event)
Definition test_cel.c:1969
static int events_are_equal(struct ast_test *test, struct ast_event *received, struct ast_event *expected)
Definition test_cel.c:1948

References ao2_cleanup, ao2_container_count(), ao2_iterator_destroy(), ao2_iterator_init(), ao2_iterator_next, AST_EVENT_CUSTOM, ast_event_get_type(), ast_test_status_update, debug, dump_event(), events_are_equal(), NULL, and RAII_VAR.

Referenced by cel_verify_and_cleanup_cb().

◆ do_sleep()

static void do_sleep ( void  )
static

◆ dump_event()

static int dump_event ( struct ast_test *  test,
struct ast_event event 
)
static

Definition at line 1969 of file test_cel.c.

1970{
1971 struct ast_event_iterator i;
1972
1973 if (ast_event_iterator_init(&i, event)) {
1974 ast_test_status_update(test, "Failed to initialize event iterator. :-(\n");
1975 return 0;
1976 }
1977
1978 ast_test_status_update(test, "Event: %s\n",
1980
1981 do {
1982 enum ast_event_ie_type ie_type;
1983 enum ast_event_ie_pltype ie_pltype;
1984 const char *ie_type_name;
1985
1986 ie_type = ast_event_iterator_get_ie_type(&i);
1987 ie_type_name = ast_event_get_ie_type_name(ie_type);
1988 ie_pltype = ast_event_get_ie_pltype(ie_type);
1989
1990 switch (ie_pltype) {
1993 ast_test_status_update(test, "%.30s: %s\n", ie_type_name,
1995 break;
1997 ast_test_status_update(test, "%.30s: %u\n", ie_type_name,
1999 break;
2000 default:
2001 break;
2002 }
2003 } while (!ast_event_iterator_next(&i));
2004
2006
2007 return 0;
2008}
const char * ast_cel_get_type_name(enum ast_cel_event_type type)
Get the name of a CEL event type.
Definition cel.c:514
const char * ast_event_get_ie_type_name(enum ast_event_ie_type ie_type)
Get the string representation of an information element type.
Definition event.c:209
uint32_t ast_event_get_ie_uint(const struct ast_event *event, enum ast_event_ie_type ie_type)
Get the value of an information element that has an integer payload.
Definition event.c:294
enum ast_event_ie_pltype ast_event_get_ie_pltype(enum ast_event_ie_type ie_type)
Get the payload type for a given information element type.
Definition event.c:219
enum ast_event_ie_type ast_event_iterator_get_ie_type(struct ast_event_iterator *iterator)
Get the type of the current IE in the iterator instance.
Definition event.c:265
int ast_event_iterator_next(struct ast_event_iterator *iterator)
Move iterator instance to next IE.
Definition event.c:259
int ast_event_iterator_init(struct ast_event_iterator *iterator, const struct ast_event *event)
Initialize an event iterator instance.
Definition event.c:243
const char * ast_event_iterator_get_ie_str(struct ast_event_iterator *iterator)
Get the value of the current IE in the iterator as a string payload.
Definition event.c:275
uint32_t ast_event_iterator_get_ie_uint(struct ast_event_iterator *iterator)
Get the value of the current IE in the iterator as an integer payload.
Definition event.c:270
ast_event_ie_type
Event Information Element types.
Definition event_defs.h:68
@ AST_EVENT_IE_CEL_EVENT_TYPE
Channel Event Type Used by: AST_EVENT_CEL Payload type: UINT.
Definition event_defs.h:133
ast_event_ie_pltype
Payload types for event information elements.
Definition event_defs.h:328
@ AST_EVENT_IE_PLTYPE_UINT
Definition event_defs.h:333
@ AST_EVENT_IE_PLTYPE_STR
Definition event_defs.h:335
@ AST_EVENT_IE_PLTYPE_UNKNOWN
Definition event_defs.h:329
supposed to be an opaque type
Definition event_defs.h:359

References ast_cel_get_type_name(), ast_event_get_ie_pltype(), ast_event_get_ie_type_name(), ast_event_get_ie_uint(), AST_EVENT_IE_CEL_EVENT_TYPE, AST_EVENT_IE_PLTYPE_STR, AST_EVENT_IE_PLTYPE_UINT, AST_EVENT_IE_PLTYPE_UNKNOWN, ast_event_iterator_get_ie_str(), ast_event_iterator_get_ie_type(), ast_event_iterator_get_ie_uint(), ast_event_iterator_init(), ast_event_iterator_next(), and ast_test_status_update.

Referenced by check_events().

◆ events_are_equal()

static int events_are_equal ( struct ast_test *  test,
struct ast_event received,
struct ast_event expected 
)
static

Definition at line 1948 of file test_cel.c.

1949{
1950 struct ast_event_iterator iterator;
1951 int res;
1952
1953 if (ast_event_get_type(expected) == AST_EVENT_CUSTOM) {
1954 /* this event is flagged as a wildcard match */
1955 return 1;
1956 }
1957
1958 for (res = ast_event_iterator_init(&iterator, received); !res; res = ast_event_iterator_next(&iterator)) {
1959 int ie_type = ast_event_iterator_get_ie_type(&iterator);
1960 if (!match_ie_val(received, expected, ie_type)) {
1961 ast_test_status_update(test, "Failed matching on field %s\n", ast_event_get_ie_type_name(ie_type));
1962 return 0;
1963 }
1964 }
1965
1966 return 1;
1967}
static int match_ie_val(const struct ast_event *event1, const struct ast_event *event2, enum ast_event_ie_type type)
Check an IE value from two events.
Definition test_cel.c:1895

References AST_EVENT_CUSTOM, ast_event_get_ie_type_name(), ast_event_get_type(), ast_event_iterator_get_ie_type(), ast_event_iterator_init(), ast_event_iterator_next(), ast_test_status_update, and match_ie_val().

Referenced by check_events().

◆ load_module()

static int load_module ( void  )
static

Definition at line 2156 of file test_cel.c.

2157{
2158 /* build the test config */
2160 if (!cel_test_config) {
2161 return -1;
2162 }
2165 return -1;
2166 }
2168 return -1;
2169 }
2171 return -1;
2172 }
2184
2186
2187 AST_TEST_REGISTER(test_cel_channel_creation);
2188 AST_TEST_REGISTER(test_cel_unanswered_inbound_call);
2189 AST_TEST_REGISTER(test_cel_unanswered_outbound_call);
2190
2191 AST_TEST_REGISTER(test_cel_single_party);
2192 AST_TEST_REGISTER(test_cel_single_bridge);
2193 AST_TEST_REGISTER(test_cel_single_bridge_continue);
2194 AST_TEST_REGISTER(test_cel_single_twoparty_bridge_a);
2195 AST_TEST_REGISTER(test_cel_single_twoparty_bridge_b);
2196#ifdef RACEY_TESTS
2197 AST_TEST_REGISTER(test_cel_single_multiparty_bridge);
2198#endif
2199
2200 AST_TEST_REGISTER(test_cel_dial_unanswered);
2201 AST_TEST_REGISTER(test_cel_dial_unanswered_filter);
2202 AST_TEST_REGISTER(test_cel_dial_congestion);
2203 AST_TEST_REGISTER(test_cel_dial_busy);
2204 AST_TEST_REGISTER(test_cel_dial_unavailable);
2205 AST_TEST_REGISTER(test_cel_dial_caller_cancel);
2206 AST_TEST_REGISTER(test_cel_dial_parallel_failed);
2207 AST_TEST_REGISTER(test_cel_dial_answer_no_bridge);
2208 AST_TEST_REGISTER(test_cel_dial_answer_twoparty_bridge_a);
2209 AST_TEST_REGISTER(test_cel_dial_answer_twoparty_bridge_b);
2210#ifdef RACEY_TESTS
2211 AST_TEST_REGISTER(test_cel_dial_answer_multiparty);
2212 AST_TEST_REGISTER(test_cel_attended_transfer_bridges_swap);
2213 AST_TEST_REGISTER(test_cel_attended_transfer_bridges_link);
2214#endif
2215
2216 AST_TEST_REGISTER(test_cel_blind_transfer);
2217 AST_TEST_REGISTER(test_cel_attended_transfer_bridges_merge);
2218
2219 AST_TEST_REGISTER(test_cel_dial_pickup);
2220
2221 AST_TEST_REGISTER(test_cel_local_optimize);
2222
2223 /* ast_test_register_* has to happen after AST_TEST_REGISTER */
2224 /* Verify received vs expected events and clean things up after every test */
2225 ast_test_register_init(TEST_CATEGORY, test_cel_init_cb);
2226 ast_test_register_cleanup(TEST_CATEGORY, cel_verify_and_cleanup_cb);
2227
2229}
void * ast_cel_general_config_alloc(void)
Allocate a CEL configuration object.
Definition cel.c:207
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
@ AST_MODULE_LOAD_SUCCESS
Definition module.h:70
int ast_str_container_add(struct ao2_container *str_container, const char *add)
Adds a string to a string container allocated by ast_str_container_alloc.
Definition strings.c:205
struct ao2_container * apps
Definition cel.h:239
#define AST_TEST_REGISTER(cb)
Definition test.h:127
static int cel_verify_and_cleanup_cb(struct ast_test_info *info, struct ast_test *test)
Definition test_cel.c:2076
static struct ast_channel_tech test_cel_chan_tech
A channel technology used for the unit tests.
Definition test_cel.c:79
static int test_cel_init_cb(struct ast_test_info *info, struct ast_test *test)
Definition test_cel.c:1825
static struct ast_cel_general_config * cel_test_config
The CEL config used for CEL unit tests.
Definition test_cel.c:64

References ast_cel_general_config::apps, AST_CEL_ANSWER, AST_CEL_APP_START, AST_CEL_ATTENDEDTRANSFER, AST_CEL_BLINDTRANSFER, AST_CEL_BRIDGE_ENTER, AST_CEL_BRIDGE_EXIT, AST_CEL_CHANNEL_END, AST_CEL_CHANNEL_START, ast_cel_general_config_alloc(), AST_CEL_HANGUP, AST_CEL_LOCAL_OPTIMIZE, AST_CEL_PICKUP, ast_channel_register(), AST_MODULE_LOAD_SUCCESS, ast_str_container_add(), AST_TEST_REGISTER, cel_test_config, cel_verify_and_cleanup_cb(), ast_cel_general_config::enable, ast_cel_general_config::events, TEST_CATEGORY, test_cel_chan_tech, and test_cel_init_cb().

◆ match_ie_val()

static int match_ie_val ( const struct ast_event event1,
const struct ast_event event2,
enum ast_event_ie_type  type 
)
static

Check an IE value from two events.

Return values
zeroif the IEs in the events of the specified type do not match
non-zeroif the IEs in the events of the specified type match

Definition at line 1895 of file test_cel.c.

1899{
1901
1902 /* XXX ignore sec/usec for now */
1904 return 1;
1905 }
1906
1908 return 1;
1909 }
1910
1911 switch (pltype) {
1913 {
1914 uint32_t val = ast_event_get_ie_uint(event2, type);
1915
1916 return (val == ast_event_get_ie_uint(event1, type)) ? 1 : 0;
1917 }
1919 {
1920 const char *str1 = ast_event_get_ie_str(event1, type);
1921 const char *str2 = ast_event_get_ie_str(event2, type);
1922
1923 if (!str1 && !str2) {
1924 return 1;
1925 } else if (!str1) {
1926 return 0;
1927 } else if (!str2) {
1928 return 0;
1929 }
1930
1931 /* use special matching for CEL PEER field */
1932 if (type == AST_EVENT_IE_CEL_PEER) {
1933 return test_cel_peer_strings_match(str1, str2);
1934 }
1935
1936 return !strcmp(str1, str2);
1937 }
1940 /* Fall through: just pass on these types */
1941 return 1;
1942 default:
1943 break;
1944 }
1945 return 0;
1946}
const char * ast_event_get_ie_str(const struct ast_event *event, enum ast_event_ie_type ie_type)
Get the value of an information element that has a string payload.
Definition event.c:303
@ AST_EVENT_IE_CEL_EVENT_TIME
Channel Event Time (seconds) Used by: AST_EVENT_CEL Payload type: UINT.
Definition event_defs.h:139
@ AST_EVENT_IE_CEL_EVENT_TIME_USEC
Channel Event Time (micro-seconds) Used by: AST_EVENT_CEL Payload type: UINT.
Definition event_defs.h:145
@ AST_EVENT_IE_CEL_PEER
Channel Event Peer – for Things involving multiple channels, like BRIDGE Used by: AST_EVENT_CEL Paylo...
Definition event_defs.h:241
@ AST_EVENT_IE_PLTYPE_RAW
Definition event_defs.h:337
@ AST_EVENT_IE_PLTYPE_BITFLAGS
Definition event_defs.h:339
static int test_cel_peer_strings_match(const char *str1, const char *str2)
Check two peer strings for equality.
Definition test_cel.c:1855

References ast_event_get_ie_pltype(), ast_event_get_ie_str(), ast_event_get_ie_uint(), AST_EVENT_IE_CEL_EVENT_TIME, AST_EVENT_IE_CEL_EVENT_TIME_USEC, AST_EVENT_IE_CEL_PEER, AST_EVENT_IE_PLTYPE_BITFLAGS, AST_EVENT_IE_PLTYPE_RAW, AST_EVENT_IE_PLTYPE_STR, AST_EVENT_IE_PLTYPE_UINT, test_cel_peer_strings_match(), and type.

Referenced by events_are_equal().

◆ mid_test_sync()

static void mid_test_sync ( void  )
static

Definition at line 1706 of file test_cel.c.

1707{
1711 return;
1712 }
1713
1714 do_mid_test_sync = 1;
1716
1717 {
1718 struct timeval start = ast_tvnow();
1719 struct timespec end = {
1720 .tv_sec = start.tv_sec + 15,
1721 .tv_nsec = start.tv_usec * 1000
1722 };
1723
1726 }
1727}
char * end
Definition eagi_proxy.c:73
#define ast_cond_timedwait(cond, mutex, time)
Definition lock.h:213
#define ast_mutex_unlock(a)
Definition lock.h:197
#define SCOPED_MUTEX(varname, lock)
scoped lock specialization for mutexes
Definition lock.h:596
#define ast_mutex_lock(a)
Definition lock.h:196
int do_mid_test_sync
Flag used to trigger a mid-test synchronization, access controlled by mid_test_sync_lock.
Definition test_cel.c:76
struct timeval ast_tvnow(void)
Returns current timeval. Meant to replace calls to gettimeofday().
Definition time.h:159

References ao2_container_count(), ast_cond_timedwait, ast_mutex_lock, ast_mutex_unlock, ast_tvnow(), cel_expected_events, cel_received_events, do_mid_test_sync, end, lock, mid_test_sync_lock, SCOPED_MUTEX, sync_lock, and sync_out.

◆ safe_bridge_destroy()

static void safe_bridge_destroy ( struct ast_bridge bridge)
static

Definition at line 385 of file test_cel.c.

386{
387 if (!bridge) {
388 return;
389 }
390 ast_bridge_destroy(bridge, 0);
391}
int ast_bridge_destroy(struct ast_bridge *bridge, int cause)
Destroy a bridge.
Definition bridge.c:1009

References ast_bridge_destroy().

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

◆ safe_channel_release()

static void safe_channel_release ( struct ast_channel chan)
static

◆ test_cel_generate_peer_str()

static struct ast_str * test_cel_generate_peer_str ( struct ast_channel chan,
struct ast_bridge bridge 
)
static

Definition at line 364 of file test_cel.c.

365{
366 RAII_VAR(struct ast_channel_snapshot *, snapshot,
369
370 if (!snapshot) {
371 return NULL;
372 }
373
374 return test_cel_generate_peer_str_snapshot(snapshot, bridge);
375}

References ao2_cleanup, ast_channel_snapshot_get_latest(), ast_channel_uniqueid(), NULL, RAII_VAR, and test_cel_generate_peer_str_snapshot().

◆ test_cel_generate_peer_str_snapshot()

static struct ast_str * test_cel_generate_peer_str_snapshot ( struct ast_channel_snapshot chan,
struct ast_bridge bridge 
)
static

Definition at line 351 of file test_cel.c.

352{
353 RAII_VAR(struct ast_bridge_snapshot *, snapshot,
356
357 if (!snapshot) {
358 return NULL;
359 }
360
361 return __test_cel_generate_peer_str(chan, snapshot);
362}
struct ast_bridge_snapshot * ast_bridge_get_snapshot(struct ast_bridge *bridge)
Returns the current snapshot for the bridge.
Structure that contains a snapshot of information about a bridge.
Definition bridge.h:318
static struct ast_str * __test_cel_generate_peer_str(struct ast_channel_snapshot *chan, struct ast_bridge_snapshot *bridge)
Definition test_cel.c:314

References __test_cel_generate_peer_str(), ao2_cleanup, ast_bridge_get_snapshot(), NULL, and RAII_VAR.

Referenced by test_cel_generate_peer_str().

◆ test_cel_init_cb()

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

Definition at line 1825 of file test_cel.c.

1826{
1829
1833
1834 /* Back up the real CEL config and insert the test's config */
1837
1838 /* init CEL event storage (degenerate hash table becomes a linked list) */
1841
1842 /* start the CEL event callback */
1844 return -1;
1845 }
1846 return 0;
1847}
@ AO2_ALLOC_OPT_LOCK_MUTEX
Definition astobj2.h:363
#define ao2_container_alloc_list(ao2_options, container_options, sort_fn, cmp_fn)
Allocate and initialize a list container.
Definition astobj2.h:1327
struct ast_cel_general_config * ast_cel_get_config(void)
Obtain the current CEL configuration.
Definition cel.c:1759
int ast_cel_backend_register(const char *name, ast_cel_backend_cb backend_callback)
Register a CEL backend.
Definition cel.c:1809
#define ast_cond_init(cond, attr)
Definition lock.h:208
#define ast_mutex_init(pmutex)
Definition lock.h:193
static void test_sub(struct ast_event *event)
Definition test_cel.c:1790

References AO2_ALLOC_OPT_LOCK_MUTEX, ao2_container_alloc_list, ast_assert, ast_cel_backend_register(), ast_cel_get_config(), ast_cel_set_config(), ast_cond_init, ast_mutex_init, cel_expected_events, cel_received_events, cel_test_config, mid_test_sync_lock, NULL, saved_config, sync_lock, sync_out, TEST_BACKEND_NAME, and test_sub().

Referenced by load_module().

◆ test_cel_peer_strings_match()

static int test_cel_peer_strings_match ( const char *  str1,
const char *  str2 
)
static

Check two peer strings for equality.

Return values
zeroif the peer strings do not match
non-zeroif the peer strings match

Definition at line 1855 of file test_cel.c.

1856{
1857 RAII_VAR(struct ao2_container *, intersection, ast_str_container_alloc(11), ao2_cleanup);
1858 RAII_VAR(char *, str1_dup, ast_strdup(str1), ast_free);
1859 RAII_VAR(char *, str2_dup, ast_strdup(str2), ast_free);
1860 char *chan;
1861
1862 if (!intersection) {
1863 return 1;
1864 }
1865
1866 while ((chan = strsep(&str1_dup, ","))) {
1867 ast_str_container_add(intersection, chan);
1868 }
1869
1870 while ((chan = strsep(&str2_dup, ","))) {
1871 RAII_VAR(char *, ao2_chan, ao2_find(intersection, chan, OBJ_SEARCH_KEY), ao2_cleanup);
1872
1873 /* item in str2 not in str1 */
1874 if (!ao2_chan) {
1875 return 0;
1876 }
1877
1878 ast_str_container_remove(intersection, chan);
1879 }
1880
1881 /* item in str1 not in str2 */
1882 if (ao2_container_count(intersection)) {
1883 return 0;
1884 }
1885
1886 return 1;
1887}
char * strsep(char **str, const char *delims)
#define ast_strdup(str)
A wrapper for strdup()
Definition astmm.h:241
#define ao2_find(container, arg, flags)
Definition astobj2.h:1736
@ OBJ_SEARCH_KEY
The arg parameter is a search key, but is not an object.
Definition astobj2.h:1101
#define ast_str_container_alloc(buckets)
Allocates a hash container for bare strings.
Definition strings.h:1365
void ast_str_container_remove(struct ao2_container *str_container, const char *remove)
Removes a string from a string container allocated by ast_str_container_alloc.
Definition strings.c:221

References ao2_cleanup, ao2_container_count(), ao2_find, ast_free, ast_str_container_add(), ast_str_container_alloc, ast_str_container_remove(), ast_strdup, OBJ_SEARCH_KEY, RAII_VAR, and strsep().

Referenced by match_ie_val().

◆ test_sub()

static void test_sub ( struct ast_event event)
static

Definition at line 1790 of file test_cel.c.

1791{
1792 RAII_VAR(struct ast_event *, event_dup, ao2_dup_event(event), ao2_cleanup);
1793 const char *chan_name;
1794 SCOPED_MUTEX(mid_test_lock, &mid_test_sync_lock);
1795
1796 if (!event_dup) {
1797 return;
1798 }
1799
1800 chan_name = ast_event_get_ie_str(event_dup, AST_EVENT_IE_CEL_CHANNAME);
1801 if (chan_name && strncmp(chan_name, CHANNEL_TECH_NAME, 14)) {
1802 return;
1803 }
1804
1805 /* save the event for later processing */
1806 ao2_link(cel_received_events, event_dup);
1807
1808 if (do_mid_test_sync) {
1811 if (expected <= received) {
1812 {
1815 do_mid_test_sync = 0;
1816 }
1817 }
1818 }
1819}
@ AST_EVENT_IE_CEL_CHANNAME
Channel Event channel name Used by: AST_EVENT_CEL Payload type: STR.
Definition event_defs.h:181
#define ast_cond_signal(cond)
Definition lock.h:210

References ao2_cleanup, ao2_container_count(), ao2_dup_event(), ao2_link, ast_cond_signal, ast_event_get_ie_str(), AST_EVENT_IE_CEL_CHANNAME, cel_expected_events, cel_received_events, CHANNEL_TECH_NAME, do_mid_test_sync, lock, mid_test_sync_lock, RAII_VAR, SCOPED_MUTEX, sync_lock, and sync_out.

Referenced by test_cel_init_cb().

◆ unload_module()

static int unload_module ( void  )
static

Definition at line 2107 of file test_cel.c.

2108{
2109 AST_TEST_UNREGISTER(test_cel_channel_creation);
2110 AST_TEST_UNREGISTER(test_cel_unanswered_inbound_call);
2111 AST_TEST_UNREGISTER(test_cel_unanswered_outbound_call);
2112 AST_TEST_UNREGISTER(test_cel_single_party);
2113 AST_TEST_UNREGISTER(test_cel_single_bridge);
2114 AST_TEST_UNREGISTER(test_cel_single_bridge_continue);
2115 AST_TEST_UNREGISTER(test_cel_single_twoparty_bridge_a);
2116 AST_TEST_UNREGISTER(test_cel_single_twoparty_bridge_b);
2117#ifdef RACEY_TESTS
2118 AST_TEST_UNREGISTER(test_cel_single_multiparty_bridge);
2119#endif
2120
2121 AST_TEST_UNREGISTER(test_cel_dial_unanswered);
2122 AST_TEST_UNREGISTER(test_cel_dial_unanswered_filter);
2123 AST_TEST_UNREGISTER(test_cel_dial_congestion);
2124 AST_TEST_UNREGISTER(test_cel_dial_busy);
2125 AST_TEST_UNREGISTER(test_cel_dial_unavailable);
2126 AST_TEST_UNREGISTER(test_cel_dial_caller_cancel);
2127 AST_TEST_UNREGISTER(test_cel_dial_parallel_failed);
2128 AST_TEST_UNREGISTER(test_cel_dial_answer_no_bridge);
2129 AST_TEST_UNREGISTER(test_cel_dial_answer_twoparty_bridge_a);
2130 AST_TEST_UNREGISTER(test_cel_dial_answer_twoparty_bridge_b);
2131#ifdef RACEY_TESTS
2132 AST_TEST_UNREGISTER(test_cel_dial_answer_multiparty);
2133 AST_TEST_UNREGISTER(test_cel_attended_transfer_bridges_swap);
2134 AST_TEST_UNREGISTER(test_cel_attended_transfer_bridges_link);
2135#endif
2136
2137 AST_TEST_UNREGISTER(test_cel_blind_transfer);
2138 AST_TEST_UNREGISTER(test_cel_attended_transfer_bridges_merge);
2139
2140 AST_TEST_UNREGISTER(test_cel_dial_pickup);
2141
2142 AST_TEST_UNREGISTER(test_cel_local_optimize);
2143
2145
2152
2153 return 0;
2154}
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 ao2_cleanup, ast_channel_unregister(), AST_TEST_UNREGISTER, cel_expected_events, cel_received_events, cel_test_config, NULL, and test_cel_chan_tech.

Variable Documentation

◆ __mod_info

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

Definition at line 2231 of file test_cel.c.

◆ ast_module_info

const struct ast_module_info* ast_module_info = &__mod_info
static

Definition at line 2231 of file test_cel.c.

◆ cel_expected_events

struct ao2_container* cel_expected_events = NULL
static

Container for expected CEL events

Definition at line 1687 of file test_cel.c.

Referenced by append_event(), cel_verify_and_cleanup_cb(), mid_test_sync(), test_cel_init_cb(), test_sub(), and unload_module().

◆ cel_received_events

struct ao2_container* cel_received_events = NULL
static

Container for astobj2 duplicated ast_events

Definition at line 1684 of file test_cel.c.

Referenced by cel_verify_and_cleanup_cb(), mid_test_sync(), test_cel_init_cb(), test_sub(), and unload_module().

◆ cel_test_config

struct ast_cel_general_config* cel_test_config
static

The CEL config used for CEL unit tests.

Definition at line 64 of file test_cel.c.

Referenced by load_module(), test_cel_init_cb(), and unload_module().

◆ do_mid_test_sync

int do_mid_test_sync = 0

Flag used to trigger a mid-test synchronization, access controlled by mid_test_sync_lock.

Definition at line 76 of file test_cel.c.

Referenced by mid_test_sync(), and test_sub().

◆ mid_test_sync_lock

ast_mutex_t mid_test_sync_lock

Lock used for synchronizing test execution stages with received events.

Definition at line 67 of file test_cel.c.

Referenced by cel_verify_and_cleanup_cb(), mid_test_sync(), test_cel_init_cb(), and test_sub().

◆ saved_config

struct ast_cel_general_config* saved_config
static

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

Definition at line 61 of file test_cel.c.

Referenced by cel_verify_and_cleanup_cb(), and test_cel_init_cb().

◆ sync_lock

ast_mutex_t sync_lock

Lock used with sync_out for checking the end of test execution.

Definition at line 70 of file test_cel.c.

Referenced by cel_verify_and_cleanup_cb(), mid_test_sync(), test_cel_init_cb(), and test_sub().

◆ sync_out

ast_cond_t sync_out

Condition used for checking the end of test execution.

Definition at line 73 of file test_cel.c.

Referenced by cel_verify_and_cleanup_cb(), mid_test_sync(), test_cel_init_cb(), and test_sub().

◆ test_cel_chan_tech

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

A channel technology used for the unit tests.

Definition at line 79 of file test_cel.c.

79 {
80 .type = CHANNEL_TECH_NAME,
81 .description = "Mock channel technology for CEL tests",
82};

Referenced by load_module(), and unload_module().

◆ to_sleep

struct timespec to_sleep = {1, 0}
static