Asterisk - The Open Source Telephony Project  21.4.1
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"

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_channel_creation)
 
 AST_TEST_DEFINE (test_cel_unanswered_inbound_call)
 
 AST_TEST_DEFINE (test_cel_unanswered_outbound_call)
 
 AST_TEST_DEFINE (test_cel_single_party)
 
 AST_TEST_DEFINE (test_cel_single_bridge)
 
 AST_TEST_DEFINE (test_cel_single_bridge_continue)
 
 AST_TEST_DEFINE (test_cel_single_twoparty_bridge_a)
 
 AST_TEST_DEFINE (test_cel_single_twoparty_bridge_b)
 
 AST_TEST_DEFINE (test_cel_dial_unanswered)
 
 AST_TEST_DEFINE (test_cel_dial_unanswered_filter)
 
 AST_TEST_DEFINE (test_cel_dial_busy)
 
 AST_TEST_DEFINE (test_cel_dial_congestion)
 
 AST_TEST_DEFINE (test_cel_dial_unavailable)
 
 AST_TEST_DEFINE (test_cel_dial_caller_cancel)
 
 AST_TEST_DEFINE (test_cel_dial_parallel_failed)
 
 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_blind_transfer)
 
 AST_TEST_DEFINE (test_cel_attended_transfer_bridges_merge)
 
 AST_TEST_DEFINE (test_cel_dial_pickup)
 
 AST_TEST_DEFINE (test_cel_local_optimize)
 
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. More...
 
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. More...
 
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 = "This paragraph is copyright (c) 2006 by Digium, Inc. \In order for your module to load, it must return this \key via a function called \"key\". Any code which \includes this paragraph must be licensed under the GNU \General Public License version 2 or later (at your \option). In addition to Digium's general reservations \of rights, Digium expressly reserves the right to \allow other parties to license this paragraph under \different terms. Any use of Digium, Inc. trademarks or \logos (including \"Asterisk\" or \"Digium\") without \express written permission of Digium, Inc. is prohibited.\n" , .buildopt_sum = AST_BUILDOPT_SUM, .load = load_module, .unload = unload_module, .load_pri = AST_MODPRI_DEFAULT, .support_level = AST_MODULE_SUPPORT_CORE, }
 
static 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. More...
 
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

#define ANSWER_CHANNEL (   chan)
Value:
do { \
EMULATE_APP_DATA(chan, 1, "Answer", ""); \
ANSWER_NO_APP(chan); \
} while (0)
#define EMULATE_APP_DATA(channel, priority, application, data)
Emulate a channel entering into an application.
Definition: test_cel.c:253

Definition at line 262 of file test_cel.c.

#define ANSWER_NO_APP (   chan)
Value:
do { \
APPEND_EVENT(chan, AST_CEL_ANSWER, NULL, NULL); \
} while (0)
A ringing phone is answered.
Definition: cel.h:51
int ast_setstate(struct ast_channel *chan, enum ast_channel_state)
Change the state of a channel.
Definition: channel.c:7386

Definition at line 267 of file test_cel.c.

#define APPEND_DUMMY_EVENT ( )
Value:
do { \
if (append_dummy_event()) { \
return AST_TEST_FAIL; \
} \
} while (0)

Definition at line 111 of file test_cel.c.

#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)

Definition at line 93 of file test_cel.c.

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

#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)

Definition at line 105 of file test_cel.c.

#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:1906

Definition at line 117 of file test_cel.c.

Function Documentation

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.

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, and test_cel_peer_strings_match().

1899 {
1900  enum ast_event_ie_pltype pltype = ast_event_get_ie_pltype(type);
1901 
1902  /* XXX ignore sec/usec for now */
1903  if (type == AST_EVENT_IE_CEL_EVENT_TIME_USEC) {
1904  return 1;
1905  }
1906 
1907  if (type == AST_EVENT_IE_CEL_EVENT_TIME) {
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 }
ast_event_ie_pltype
Payload types for event information elements.
Definition: event_defs.h:321
static int test_cel_peer_strings_match(const char *str1, const char *str2)
Check two peer strings for equality.
Definition: test_cel.c:1855
Channel Event Time (micro-seconds) Used by: AST_EVENT_CEL Payload type: UINT.
Definition: event_defs.h:145
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:218
Channel Event Time (seconds) Used by: AST_EVENT_CEL Payload type: UINT.
Definition: event_defs.h:139
Channel Event Peer – for Things involving multiple channels, like BRIDGE Used by: AST_EVENT_CEL Payl...
Definition: event_defs.h:241
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:293
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:302
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.

References ao2_container_count(), ast_str_container_add(), ast_str_container_alloc, ast_str_container_remove(), ast_strdup, OBJ_SEARCH_KEY, and RAII_VAR.

Referenced by match_ie_val().

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 }
int ao2_container_count(struct ao2_container *c)
Returns the number of elements in a container.
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
#define ast_strdup(str)
A wrapper for strdup()
Definition: astmm.h:241
Generic container type.
#define RAII_VAR(vartype, varname, initval, dtor)
Declare a variable that will call a destructor function when it goes out of scope.
Definition: utils.h:941
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

Variable Documentation

struct ao2_container* cel_expected_events = NULL
static

Container for expected CEL events

Definition at line 1687 of file test_cel.c.

struct ao2_container* cel_received_events = NULL
static

Container for astobj2 duplicated ast_events

Definition at line 1684 of file test_cel.c.

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

A channel technology used for the unit tests.

Definition at line 79 of file test_cel.c.