Asterisk - The Open Source Telephony Project  18.5.0
Data Structures | Macros | Functions | Variables
test_bridging.c File Reference

Bridging unit tests. More...

#include "asterisk.h"
#include "asterisk/module.h"
#include "asterisk/test.h"
#include "asterisk/channel.h"
#include "asterisk/time.h"
#include "asterisk/bridge.h"
#include "asterisk/bridge_basic.h"
#include "asterisk/features.h"
#include "asterisk/format_cache.h"
Include dependency graph for test_bridging.c:

Go to the source code of this file.

Data Structures

struct  test_bridging_chan_pvt
 A private structure for the test channel. More...
 

Macros

#define CHANNEL_TECH_NAME   "BridgingTestChannel"
 
#define HANGUP_CHANNEL(channel)
 Hang up a test channel safely. More...
 
#define START_ALICE(channel, pvt)   START_CHANNEL(channel, pvt, "Alice", "100")
 Create a test_bridging_chan_tech for Alice. More...
 
#define START_BOB(channel, pvt)   START_CHANNEL(channel, pvt, "Bob", "200")
 Create a test_bridging_chan_tech for Bob. More...
 
#define START_CHANNEL(channel, pvt, name, number)
 
#define TEST_CATEGORY   "/main/bridging/"
 
#define TEST_CHANNEL_FORMAT   ast_format_slin
 

Functions

static void __reg_module (void)
 
static void __unreg_module (void)
 
struct ast_moduleAST_MODULE_SELF_SYM (void)
 
 AST_TEST_DEFINE (test_bridging_deferred_queue)
 
static int load_module (void)
 
static void safe_bridge_destroy (struct ast_bridge *bridge)
 
static void safe_channel_release (struct ast_channel *chan)
 
static void stream_periodic_frames (struct ast_channel *chan, int ms, int interval_ms)
 
static int test_bridging_chan_hangup (struct ast_channel *chan)
 Callback function for when a channel is hung up. More...
 
static int test_bridging_chan_indicate (struct ast_channel *chan, int condition, const void *data, size_t datalen)
 Callback function for when a frame is written to a channel. More...
 
static void test_nanosleep (int secs, long nanosecs)
 
static int unload_module (void)
 
static void wait_for_bridged (struct ast_channel *channel)
 Wait until a channel is bridged. More...
 
static void wait_for_empty_queue (struct ast_channel *channel)
 Wait until a channel has no frames on its read queue. More...
 
static void wait_for_unbridged (struct ast_channel *channel)
 Wait until a channel is not bridged. More...
 

Variables

static struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_LOAD_ORDER , .description = "Bridging 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 ast_channel_tech test_bridging_chan_tech
 A channel technology used for the unit tests. More...
 

Detailed Description

Bridging unit tests.

Author
Joshua Colp jcolp.nosp@m.@dig.nosp@m.ium.c.nosp@m.om

Definition in file test_bridging.c.

Macro Definition Documentation

◆ CHANNEL_TECH_NAME

#define CHANNEL_TECH_NAME   "BridgingTestChannel"

Definition at line 45 of file test_bridging.c.

◆ HANGUP_CHANNEL

#define HANGUP_CHANNEL (   channel)

Hang up a test channel safely.

Definition at line 153 of file test_bridging.c.

Referenced by AST_TEST_DEFINE().

◆ START_ALICE

#define START_ALICE (   channel,
  pvt 
)    START_CHANNEL(channel, pvt, "Alice", "100")

Create a test_bridging_chan_tech for Alice.

Definition at line 134 of file test_bridging.c.

Referenced by AST_TEST_DEFINE().

◆ START_BOB

#define START_BOB (   channel,
  pvt 
)    START_CHANNEL(channel, pvt, "Bob", "200")

Create a test_bridging_chan_tech for Bob.

Definition at line 137 of file test_bridging.c.

Referenced by AST_TEST_DEFINE().

◆ START_CHANNEL

#define START_CHANNEL (   channel,
  pvt,
  name,
  number 
)

Definition at line 139 of file test_bridging.c.

◆ TEST_CATEGORY

#define TEST_CATEGORY   "/main/bridging/"

Definition at line 43 of file test_bridging.c.

Referenced by AST_TEST_DEFINE().

◆ TEST_CHANNEL_FORMAT

#define TEST_CHANNEL_FORMAT   ast_format_slin

Definition at line 47 of file test_bridging.c.

Referenced by load_module().

Function Documentation

◆ __reg_module()

static void __reg_module ( void  )
static

Definition at line 290 of file test_bridging.c.

◆ __unreg_module()

static void __unreg_module ( void  )
static

Definition at line 290 of file test_bridging.c.

◆ AST_MODULE_SELF_SYM()

struct ast_module* AST_MODULE_SELF_SYM ( void  )

Definition at line 290 of file test_bridging.c.

◆ AST_TEST_DEFINE()

AST_TEST_DEFINE ( test_bridging_deferred_queue  )

Definition at line 198 of file test_bridging.c.

References ast_bridge_basic_new(), ast_bridge_depart(), ast_bridge_impart(), AST_BRIDGE_IMPART_CHAN_DEPARTABLE, AST_CONTROL_T38_PARAMETERS, AST_FRAME_CONTROL, ast_queue_frame(), AST_T38_REQUEST_NEGOTIATE, AST_TEST_NOT_RUN, AST_TEST_PASS, test_bridging_chan_pvt::condition, ast_frame::frametype, HANGUP_CHANNEL, test_bridging_chan_pvt::indicated, sip_to_pjsip::info(), NULL, RAII_VAR, ast_control_t38_parameters::request_response, safe_bridge_destroy(), safe_channel_release(), START_ALICE, START_BOB, stream_periodic_frames(), TEST_CATEGORY, TEST_EXECUTE, TEST_INIT, wait_for_bridged(), wait_for_empty_queue(), and wait_for_unbridged().

199 {
200  RAII_VAR(struct ast_channel *, chan_alice, NULL, safe_channel_release);
201  struct test_bridging_chan_pvt *alice_pvt;
202  struct ast_control_t38_parameters t38_parameters = {
204  };
205  struct ast_frame frame = {
207  .subclass.integer = AST_CONTROL_T38_PARAMETERS,
208  .data.ptr = &t38_parameters,
209  .datalen = sizeof(t38_parameters),
210  };
211  RAII_VAR(struct ast_channel *, chan_bob, NULL, safe_channel_release);
212  struct test_bridging_chan_pvt *bob_pvt;
213  RAII_VAR(struct ast_bridge *, bridge1, NULL, safe_bridge_destroy);
214 
215  switch (cmd) {
216  case TEST_INIT:
217  info->name = __func__;
218  info->category = TEST_CATEGORY;
219  info->summary = "Test that deferred frames from a channel in a bridge get written";
220  info->description =
221  "This test creates two channels, queues a deferrable frame on one, places it into\n"
222  "a bridge, confirms the frame was read by the bridge, adds the second channel to the\n"
223  "bridge, and makes sure the deferred frame is written to it.";
224  return AST_TEST_NOT_RUN;
225  case TEST_EXECUTE:
226  break;
227  }
228 
229  /* Create the bridges */
230  bridge1 = ast_bridge_basic_new();
231  ast_test_validate(test, bridge1 != NULL);
232 
233  /* Create channels that will go into the bridge */
234  START_ALICE(chan_alice, alice_pvt);
235  START_BOB(chan_bob, bob_pvt);
237 
238  /* Bridge alice and wait for the frame to be deferred */
239  ast_test_validate(test, !ast_bridge_impart(bridge1, chan_alice, NULL, NULL, AST_BRIDGE_IMPART_CHAN_DEPARTABLE));
240  wait_for_bridged(chan_alice);
241  ast_queue_frame(chan_alice, &frame);
242  wait_for_empty_queue(chan_alice);
243 
244  /* Bridge bob for a second so it can receive the deferred T.38 request negotiate frame */
245  ast_test_validate(test, !ast_bridge_impart(bridge1, chan_bob, NULL, NULL, AST_BRIDGE_IMPART_CHAN_DEPARTABLE));
246  wait_for_bridged(chan_bob);
247  stream_periodic_frames(chan_alice, 1000, 20);
248  ast_test_validate(test, !ast_bridge_depart(chan_bob));
249  wait_for_unbridged(chan_bob);
250 
251  /* Ensure that we received the expected indications while it was in there (request to negotiate, and to terminate) */
252  ast_test_validate(test, bob_pvt->indicated == 2);
253 
254  /* Now remove alice since we are done */
255  ast_test_validate(test, !ast_bridge_depart(chan_alice));
256  wait_for_unbridged(chan_alice);
257 
258  /* Hangup the channels */
259  HANGUP_CHANNEL(chan_alice);
260  HANGUP_CHANNEL(chan_bob);
261 
262  return AST_TEST_PASS;
263 }
Main Channel structure associated with a channel.
static void stream_periodic_frames(struct ast_channel *chan, int ms, int interval_ms)
#define TEST_CATEGORY
Definition: test_bridging.c:43
#define START_ALICE(channel, pvt)
Create a test_bridging_chan_tech for Alice.
A private structure for the test channel.
Definition: test_bridging.c:50
static void wait_for_unbridged(struct ast_channel *channel)
Wait until a channel is not bridged.
enum ast_control_t38 request_response
static void safe_bridge_destroy(struct ast_bridge *bridge)
#define NULL
Definition: resample.c:96
unsigned int indicated
The number of indicated things.
Definition: test_bridging.c:54
static void wait_for_bridged(struct ast_channel *channel)
Wait until a channel is bridged.
Definition: test_bridging.c:98
int ast_bridge_impart(struct ast_bridge *bridge, struct ast_channel *chan, struct ast_channel *swap, struct ast_bridge_features *features, enum ast_bridge_impart_flags flags) attribute_warn_unused_result
Impart a channel to a bridge (non-blocking)
Definition: bridge.c:1924
#define RAII_VAR(vartype, varname, initval, dtor)
Declare a variable that will call a destructor function when it goes out of scope.
Definition: utils.h:911
int ast_queue_frame(struct ast_channel *chan, struct ast_frame *f)
Queue one or more frames to a channel's frame queue.
Definition: channel.c:1139
#define HANGUP_CHANNEL(channel)
Hang up a test channel safely.
Structure that contains information about a bridge.
Definition: bridge.h:357
def info(msg)
static void wait_for_empty_queue(struct ast_channel *channel)
Wait until a channel has no frames on its read queue.
int ast_bridge_depart(struct ast_channel *chan)
Depart a channel from a bridge.
Definition: bridge.c:1952
static void safe_channel_release(struct ast_channel *chan)
struct ast_bridge * ast_bridge_basic_new(void)
Create a new basic class bridge.
Data structure associated with a single frame of data.
enum ast_frame_type frametype
#define START_BOB(channel, pvt)
Create a test_bridging_chan_tech for Bob.

◆ load_module()

static int load_module ( void  )
static

Definition at line 276 of file test_bridging.c.

References ast_channel_register(), ast_format_cap_alloc, ast_format_cap_append, AST_FORMAT_CAP_FLAG_DEFAULT, AST_MODULE_LOAD_DECLINE, AST_MODULE_LOAD_SUCCESS, AST_TEST_REGISTER, ast_channel_tech::capabilities, and TEST_CHANNEL_FORMAT.

277 {
281  }
284 
285  AST_TEST_REGISTER(test_bridging_deferred_queue);
286 
288 }
#define AST_TEST_REGISTER(cb)
Definition: test.h:127
int ast_channel_register(const struct ast_channel_tech *tech)
Register a channel technology (a new channel driver) Called by a channel module to register the kind ...
Definition: channel.c:539
#define ast_format_cap_append(cap, format, framing)
Definition: format_cap.h:103
#define ast_format_cap_alloc(flags)
Definition: format_cap.h:52
#define TEST_CHANNEL_FORMAT
Definition: test_bridging.c:47
struct ast_format_cap * capabilities
Definition: channel.h:633
Module has failed to load, may be in an inconsistent state.
Definition: module.h:78
static struct ast_channel_tech test_bridging_chan_tech
A channel technology used for the unit tests.
Definition: test_bridging.c:81

◆ safe_bridge_destroy()

static void safe_bridge_destroy ( struct ast_bridge bridge)
static

Definition at line 168 of file test_bridging.c.

References ast_bridge_destroy().

Referenced by AST_TEST_DEFINE().

169 {
170  if (!bridge) {
171  return;
172  }
173  ast_bridge_destroy(bridge, 0);
174 }
int ast_bridge_destroy(struct ast_bridge *bridge, int cause)
Destroy a bridge.
Definition: bridge.c:970

◆ safe_channel_release()

static void safe_channel_release ( struct ast_channel chan)
static

Definition at line 160 of file test_bridging.c.

References ast_channel_release().

Referenced by AST_TEST_DEFINE().

161 {
162  if (!chan) {
163  return;
164  }
165  ast_channel_release(chan);
166 }
struct ast_channel * ast_channel_release(struct ast_channel *chan)
Unlink and release reference to a channel.
Definition: channel.c:1584

◆ stream_periodic_frames()

static void stream_periodic_frames ( struct ast_channel chan,
int  ms,
int  interval_ms 
)
static

Definition at line 176 of file test_bridging.c.

References ast_assert, ast_null_frame, ast_queue_frame(), NULL, and test_nanosleep().

Referenced by AST_TEST_DEFINE().

177 {
178  long nanosecs;
179 
180  ast_assert(chan != NULL);
181  ast_assert(0 < ms);
182  ast_assert(0 < interval_ms);
183 
184  nanosecs = interval_ms * 1000000L;
185  while (0 < ms) {
187 
188  if (interval_ms < ms) {
189  ms -= interval_ms;
190  } else {
191  nanosecs = ms * 1000000L;
192  ms = 0;
193  }
194  test_nanosleep(0, nanosecs);
195  }
196 }
#define ast_assert(a)
Definition: utils.h:695
#define NULL
Definition: resample.c:96
int ast_queue_frame(struct ast_channel *chan, struct ast_frame *f)
Queue one or more frames to a channel&#39;s frame queue.
Definition: channel.c:1139
struct ast_frame ast_null_frame
Definition: main/frame.c:79
static void test_nanosleep(int secs, long nanosecs)
Definition: test_bridging.c:89

◆ test_bridging_chan_hangup()

static int test_bridging_chan_hangup ( struct ast_channel chan)
static

Callback function for when a channel is hung up.

Definition at line 70 of file test_bridging.c.

References ast_channel_tech_pvt(), ast_channel_tech_pvt_set(), ast_free, and NULL.

71 {
72  struct test_bridging_chan_pvt *test_pvt = ast_channel_tech_pvt(chan);
73 
74  ast_free(test_pvt);
76 
77  return 0;
78 }
void * ast_channel_tech_pvt(const struct ast_channel *chan)
A private structure for the test channel.
Definition: test_bridging.c:50
#define NULL
Definition: resample.c:96
#define ast_free(a)
Definition: astmm.h:182
void ast_channel_tech_pvt_set(struct ast_channel *chan, void *value)

◆ test_bridging_chan_indicate()

static int test_bridging_chan_indicate ( struct ast_channel chan,
int  condition,
const void *  data,
size_t  datalen 
)
static

Callback function for when a frame is written to a channel.

Definition at line 58 of file test_bridging.c.

References ast_channel_tech_pvt(), test_bridging_chan_pvt::condition, and test_bridging_chan_pvt::indicated.

59 {
60  struct test_bridging_chan_pvt *test_pvt = ast_channel_tech_pvt(chan);
61 
62  if (condition == test_pvt->condition) {
63  test_pvt->indicated++;
64  }
65 
66  return 0;
67 }
void * ast_channel_tech_pvt(const struct ast_channel *chan)
A private structure for the test channel.
Definition: test_bridging.c:50
unsigned int indicated
The number of indicated things.
Definition: test_bridging.c:54

◆ test_nanosleep()

static void test_nanosleep ( int  secs,
long  nanosecs 
)
static

Definition at line 89 of file test_bridging.c.

References errno.

Referenced by stream_periodic_frames(), wait_for_bridged(), wait_for_empty_queue(), and wait_for_unbridged().

90 {
91  struct timespec sleep_time = {secs, nanosecs};
92 
93  while ((nanosleep(&sleep_time, &sleep_time) == -1) && (errno == EINTR)) {
94  }
95 }
int errno

◆ unload_module()

static int unload_module ( void  )
static

Definition at line 265 of file test_bridging.c.

References ao2_cleanup, ast_channel_unregister(), AST_TEST_UNREGISTER, ast_channel_tech::capabilities, and NULL.

266 {
267  AST_TEST_UNREGISTER(test_bridging_deferred_queue);
268 
272 
273  return 0;
274 }
void ast_channel_unregister(const struct ast_channel_tech *tech)
Unregister a channel technology.
Definition: channel.c:570
#define NULL
Definition: resample.c:96
#define AST_TEST_UNREGISTER(cb)
Definition: test.h:128
struct ast_format_cap * capabilities
Definition: channel.h:633
#define ao2_cleanup(obj)
Definition: astobj2.h:1958
static struct ast_channel_tech test_bridging_chan_tech
A channel technology used for the unit tests.
Definition: test_bridging.c:81

◆ wait_for_bridged()

static void wait_for_bridged ( struct ast_channel channel)
static

Wait until a channel is bridged.

Definition at line 98 of file test_bridging.c.

References ast_channel_is_bridged(), ast_channel_lock, ast_channel_unlock, and test_nanosleep().

Referenced by AST_TEST_DEFINE().

99 {
100  ast_channel_lock(channel);
101  while (!ast_channel_is_bridged(channel)) {
102  ast_channel_unlock(channel);
103  test_nanosleep(0, 1000000);
104  ast_channel_lock(channel);
105  }
106  ast_channel_unlock(channel);
107 }
#define ast_channel_lock(chan)
Definition: channel.h:2945
int ast_channel_is_bridged(const struct ast_channel *chan)
Determine if a channel is in a bridge.
Definition: channel.c:10746
#define ast_channel_unlock(chan)
Definition: channel.h:2946
static void test_nanosleep(int secs, long nanosecs)
Definition: test_bridging.c:89

◆ wait_for_empty_queue()

static void wait_for_empty_queue ( struct ast_channel channel)
static

Wait until a channel has no frames on its read queue.

Definition at line 122 of file test_bridging.c.

References ast_channel_lock, ast_channel_readq(), ast_channel_unlock, AST_LIST_EMPTY, and test_nanosleep().

Referenced by AST_TEST_DEFINE().

123 {
124  ast_channel_lock(channel);
125  while (!AST_LIST_EMPTY(ast_channel_readq(channel))) {
126  ast_channel_unlock(channel);
127  test_nanosleep(0, 1000000);
128  ast_channel_lock(channel);
129  }
130  ast_channel_unlock(channel);
131 }
#define ast_channel_lock(chan)
Definition: channel.h:2945
#define AST_LIST_EMPTY(head)
Checks whether the specified list contains any entries.
Definition: linkedlists.h:449
struct ast_readq_list * ast_channel_readq(struct ast_channel *chan)
#define ast_channel_unlock(chan)
Definition: channel.h:2946
static void test_nanosleep(int secs, long nanosecs)
Definition: test_bridging.c:89

◆ wait_for_unbridged()

static void wait_for_unbridged ( struct ast_channel channel)
static

Wait until a channel is not bridged.

Definition at line 110 of file test_bridging.c.

References ast_channel_is_bridged(), ast_channel_lock, ast_channel_unlock, and test_nanosleep().

Referenced by AST_TEST_DEFINE().

111 {
112  ast_channel_lock(channel);
113  while (ast_channel_is_bridged(channel)) {
114  ast_channel_unlock(channel);
115  test_nanosleep(0, 1000000);
116  ast_channel_lock(channel);
117  }
118  ast_channel_unlock(channel);
119 }
#define ast_channel_lock(chan)
Definition: channel.h:2945
int ast_channel_is_bridged(const struct ast_channel *chan)
Determine if a channel is in a bridge.
Definition: channel.c:10746
#define ast_channel_unlock(chan)
Definition: channel.h:2946
static void test_nanosleep(int secs, long nanosecs)
Definition: test_bridging.c:89

Variable Documentation

◆ __mod_info

struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_LOAD_ORDER , .description = "Bridging Unit Tests" , .key = "This paragraph is copyright (c) 2006 by Digium, Inc. \In order for your module to load, it must return this \key via a function called \"key\". Any code which \includes this paragraph must be licensed under the GNU \General Public License version 2 or later (at your \option). In addition to Digium's general reservations \of rights, Digium expressly reserves the right to \allow other parties to license this paragraph under \different terms. Any use of Digium, Inc. trademarks or \logos (including \"Asterisk\" or \"Digium\") without \express written permission of Digium, Inc. is prohibited.\n" , .buildopt_sum = AST_BUILDOPT_SUM, .load = load_module, .unload = unload_module, .load_pri = AST_MODPRI_DEFAULT, .support_level = AST_MODULE_SUPPORT_CORE, }
static

Definition at line 290 of file test_bridging.c.

◆ ast_module_info

const struct ast_module_info* ast_module_info = &__mod_info
static

Definition at line 290 of file test_bridging.c.

◆ test_bridging_chan_tech

struct ast_channel_tech test_bridging_chan_tech
static

A channel technology used for the unit tests.

Definition at line 81 of file test_bridging.c.