Asterisk - The Open Source Telephony Project  GIT-master-44aef04
test_cel.c
Go to the documentation of this file.
1 /*
2  * Asterisk -- An open source telephony toolkit.
3  *
4  * Copyright (C) 2013, Digium, Inc.
5  *
6  * Kinsey Moore <kmoore@digium.com>
7  *
8  * See http://www.asterisk.org for more information about
9  * the Asterisk project. Please do not directly contact
10  * any of the maintainers of this project for assistance;
11  * the project provides a web site, mailing lists and IRC
12  * channels for your use.
13  *
14  * This program is free software, distributed under the terms of
15  * the GNU General Public License Version 2. See the LICENSE file
16  * at the top of the source tree.
17  */
18 
19 /*!
20  * \file
21  * \brief CEL unit tests
22  *
23  * \author Kinsey Moore <kmoore@digium.com>
24  *
25  */
26 
27 /*** MODULEINFO
28  <depend>TEST_FRAMEWORK</depend>
29  <support_level>core</support_level>
30  ***/
31 
32 #include "asterisk.h"
33 
34 #include <math.h>
35 #include "asterisk/module.h"
36 #include "asterisk/test.h"
37 #include "asterisk/cel.h"
38 #include "asterisk/channel.h"
39 #include "asterisk/format_cache.h"
40 #include "asterisk/linkedlists.h"
41 #include "asterisk/chanvars.h"
42 #include "asterisk/utils.h"
43 #include "asterisk/causes.h"
44 #include "asterisk/time.h"
45 #include "asterisk/bridge.h"
46 #include "asterisk/bridge_basic.h"
47 #include "asterisk/pickup.h"
50 #include "asterisk/json.h"
51 #include "asterisk/features.h"
52 #include "asterisk/core_local.h"
53 
54 #define TEST_CATEGORY "/main/cel/"
55 
56 #define CHANNEL_TECH_NAME "CELTestChannel"
57 
58 #define TEST_BACKEND_NAME "CEL Test Logging"
59 
60 /*! \brief A placeholder for Asterisk's 'real' CEL configuration */
62 
63 /*! \brief The CEL config used for CEL unit tests */
65 
66 /*! \brief Lock used for synchronizing test execution stages with received events */
68 
69 /*! \brief Lock used with sync_out for checking the end of test execution */
71 
72 /*! \brief Condition used for checking the end of test execution */
74 
75 /*! \brief Flag used to trigger a mid-test synchronization, access controlled by mid_test_sync_lock */
77 
78 /*! \brief A channel technology used for the unit tests */
81  .description = "Mock channel technology for CEL tests",
82 };
83 
84 /*! \brief A 1 second sleep */
85 static struct timespec to_sleep = {1, 0};
86 
87 static void do_sleep(void)
88 {
89  while ((nanosleep(&to_sleep, &to_sleep) == -1) && (errno == EINTR)) {
90  }
91 }
92 
93 #define APPEND_EVENT(chan, ev_type, userevent, extra) do { \
94  if (append_expected_event(chan, ev_type, userevent, extra, NULL)) { \
95  return AST_TEST_FAIL; \
96  } \
97  } while (0)
98 
99 #define APPEND_EVENT_PEER(chan, ev_type, userevent, extra, peer) do { \
100  if (append_expected_event(chan, ev_type, userevent, extra, peer)) { \
101  return AST_TEST_FAIL; \
102  } \
103  } while (0)
104 
105 #define APPEND_EVENT_SNAPSHOT(snapshot, ev_type, userevent, extra, peer) do { \
106  if (append_expected_event_snapshot(snapshot, ev_type, userevent, extra, peer)) { \
107  return AST_TEST_FAIL; \
108  } \
109  } while (0)
110 
111 #define APPEND_DUMMY_EVENT() do { \
112  if (append_dummy_event()) { \
113  return AST_TEST_FAIL; \
114  } \
115  } while (0)
116 
117 #define BRIDGE_EXIT(channel, bridge) do { \
118  ast_test_validate(test, !ast_bridge_depart(channel)); \
119  BRIDGE_EXIT_EVENT(channel, bridge); \
120  mid_test_sync(); \
121  } while (0)
122 
123 #define BRIDGE_EXIT_EVENT(channel, bridge) do { \
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)
129 
130 #define BRIDGE_EXIT_EVENT_PEER(channel, bridge, peer) do { \
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)
136 
137 #define BRIDGE_EXIT_SNAPSHOT(channel, bridge) do { \
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)
146 
147 #define BRIDGE_ENTER(channel, bridge) do { \
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)
153 
154 #define BRIDGE_ENTER_EVENT(channel, bridge) do { \
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)
160 
161 #define BRIDGE_ENTER_EVENT_PEER(channel, bridge, peer) do { \
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)
167 
168 #define BLINDTRANSFER_EVENT(channel, bridge, extension, context) do { \
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)
179 
180 #define ATTENDEDTRANSFER_BRIDGE(channel1, bridge1, channel2, bridge2, channel3, channel4) do { \
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)
194 
195 /*! \brief Alice's Caller ID */
196 #define ALICE_CALLERID { .id.name.str = "Alice", .id.name.valid = 1, .id.number.str = "100", .id.number.valid = 1, }
197 
198 /*! \brief Bob's Caller ID */
199 #define BOB_CALLERID { .id.name.str = "Bob", .id.name.valid = 1, .id.number.str = "200", .id.number.valid = 1, }
200 
201 /*! \brief Charlie's Caller ID */
202 #define CHARLIE_CALLERID { .id.name.str = "Charlie", .id.name.valid = 1, .id.number.str = "300", .id.number.valid = 1, }
203 
204 /*! \brief David's Caller ID */
205 #define DAVID_CALLERID { .id.name.str = "David", .id.name.valid = 1, .id.number.str = "400", .id.number.valid = 1, }
206 
207 /*! \brief Set ulaw format on channel */
208 #define SET_FORMATS(chan) do {\
209  struct ast_format_cap *caps;\
210  caps = ast_format_cap_alloc(AST_FORMAT_CAP_FLAG_DEFAULT);\
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)
219 
220 /*! \brief Create a \ref test_cel_chan_tech for Alice. */
221 #define CREATE_ALICE_CHANNEL(channel_var, caller_id) do { \
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)
227 
228 /*! \brief Create a \ref test_cel_chan_tech for Bob. */
229 #define CREATE_BOB_CHANNEL(channel_var, caller_id) do { \
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)
235 
236 /*! \brief Create a \ref test_cel_chan_tech for Charlie. */
237 #define CREATE_CHARLIE_CHANNEL(channel_var, caller_id) do { \
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)
243 
244 /*! \brief Create a \ref test_cel_chan_tech for David. */
245 #define CREATE_DAVID_CHANNEL(channel_var, caller_id) do { \
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)
251 
252 /*! \brief Emulate a channel entering into an application */
253 #define EMULATE_APP_DATA(channel, priority, application, data) do { \
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)
261 
262 #define ANSWER_CHANNEL(chan) do { \
263  EMULATE_APP_DATA(chan, 1, "Answer", ""); \
264  ANSWER_NO_APP(chan); \
265  } while (0)
266 
267 #define ANSWER_NO_APP(chan) do { \
268  ast_setstate(chan, AST_STATE_UP); \
269  APPEND_EVENT(chan, AST_CEL_ANSWER, NULL, NULL); \
270  } while (0)
271 
272 /*! \brief Hang up a test channel safely */
273 #define HANGUP_CHANNEL(channel, cause, dialstatus) do { \
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); \
279  ao2_cleanup(ast_channel_snapshot_get_latest(ast_channel_uniqueid(channel))); \
280  ao2_cleanup(channel); \
281  channel = NULL; \
282  } while (0)
283 
284 #define HANGUP_EVENT(channel, cause, dialstatus) do { \
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)
293 
294 static void mid_test_sync(void);
295 
296 static int append_expected_event(
297  struct ast_channel *chan,
299  const char *userdefevname,
300  struct ast_json *extra,
301  const char *peer);
302 
304  struct ast_channel_snapshot *snapshot,
306  const char *userdefevname,
307  struct ast_json *extra,
308  const char *peer);
309 
310 #ifdef RACEY_TESTS
311 static int append_dummy_event(void);
312 #endif
313 
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,
329  ao2_cleanup);
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 }
350 
352 {
353  RAII_VAR(struct ast_bridge_snapshot *, snapshot,
354  ast_bridge_get_snapshot(bridge),
355  ao2_cleanup);
356 
357  if (!snapshot) {
358  return NULL;
359  }
360 
361  return __test_cel_generate_peer_str(chan, snapshot);
362 }
363 
364 static struct ast_str *test_cel_generate_peer_str(struct ast_channel *chan, struct ast_bridge *bridge)
365 {
366  RAII_VAR(struct ast_channel_snapshot *, snapshot,
368  ao2_cleanup);
369 
370  if (!snapshot) {
371  return NULL;
372  }
373 
374  return test_cel_generate_peer_str_snapshot(snapshot, bridge);
375 }
376 
377 static void safe_channel_release(struct ast_channel *chan)
378 {
379  if (!chan) {
380  return;
381  }
382  ast_channel_release(chan);
383 }
384 
385 static void safe_bridge_destroy(struct ast_bridge *bridge)
386 {
387  if (!bridge) {
388  return;
389  }
390  ast_bridge_destroy(bridge, 0);
391 }
392 
393 AST_TEST_DEFINE(test_cel_channel_creation)
394 {
395  RAII_VAR(struct ast_channel *, chan, NULL, safe_channel_release);
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 
412  HANGUP_CHANNEL(chan, AST_CAUSE_NORMAL, "");
413 
414  return AST_TEST_PASS;
415 }
416 
417 AST_TEST_DEFINE(test_cel_unanswered_inbound_call)
418 {
419  RAII_VAR(struct ast_channel *, chan, NULL, safe_channel_release);
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 
440  HANGUP_CHANNEL(chan, AST_CAUSE_NORMAL, "");
441 
442  return AST_TEST_PASS;
443 }
444 
445 AST_TEST_DEFINE(test_cel_unanswered_outbound_call)
446 {
447  RAII_VAR(struct ast_channel *, chan, NULL, safe_channel_release);
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)");
473  HANGUP_CHANNEL(chan, AST_CAUSE_NORMAL, "");
474 
475  return AST_TEST_PASS;
476 }
477 
478 AST_TEST_DEFINE(test_cel_single_party)
479 {
480  RAII_VAR(struct ast_channel *, chan, NULL, safe_channel_release);
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 
500  HANGUP_CHANNEL(chan, AST_CAUSE_NORMAL, "");
501 
502  return AST_TEST_PASS;
503 }
504 
505 AST_TEST_DEFINE(test_cel_single_bridge)
506 {
507  RAII_VAR(struct ast_channel *, chan, NULL, safe_channel_release);
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 
539  HANGUP_CHANNEL(chan, AST_CAUSE_NORMAL, "");
540 
541  return AST_TEST_PASS;
542 }
543 
544 AST_TEST_DEFINE(test_cel_single_bridge_continue)
545 {
546  RAII_VAR(struct ast_channel *, chan, NULL, safe_channel_release);
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 */
580  HANGUP_CHANNEL(chan, AST_CAUSE_NORMAL, "");
581 
582  return AST_TEST_PASS;
583 }
584 
585 AST_TEST_DEFINE(test_cel_single_twoparty_bridge_a)
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 }
632 
633 AST_TEST_DEFINE(test_cel_single_twoparty_bridge_b)
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 }
680 
681 /* XXX Validation needs to be reworked on a per-channel basis before
682  * test_cel_single_multiparty_bridge and test_cel_dial_answer_multiparty
683  * can operate properly. */
684 #ifdef RACEY_TESTS
685 AST_TEST_DEFINE(test_cel_single_multiparty_bridge)
686 {
687  RAII_VAR(struct ast_channel *, chan_alice, NULL, safe_channel_release);
688  RAII_VAR(struct ast_channel *, chan_bob, NULL, safe_channel_release);
689  RAII_VAR(struct ast_channel *, chan_charlie, NULL, safe_channel_release);
690  RAII_VAR(struct ast_bridge *, bridge, NULL, safe_bridge_destroy);
691  struct ast_party_caller caller_alice = ALICE_CALLERID;
692  struct ast_party_caller caller_bob = BOB_CALLERID;
693  struct ast_party_caller caller_charlie = CHARLIE_CALLERID;
694 
695  switch (cmd) {
696  case TEST_INIT:
697  info->name = __func__;
698  info->category = TEST_CATEGORY;
699  info->summary = "Test CEL for a single party entering/leaving a multi-party bridge";
700  info->description =
701  "Test CEL records for a call that is\n"
702  "answered, enters a bridge, and leaves it. A total of three\n"
703  "parties perform this action.";
704  return AST_TEST_NOT_RUN;
705  case TEST_EXECUTE:
706  break;
707  }
708  bridge = ast_bridge_basic_new();
709  ast_test_validate(test, bridge != NULL);
710 
711  CREATE_ALICE_CHANNEL(chan_alice, &caller_alice);
712  CREATE_BOB_CHANNEL(chan_bob, &caller_bob);
713  CREATE_CHARLIE_CHANNEL(chan_charlie, &caller_charlie);
714 
715  ANSWER_CHANNEL(chan_alice);
716  EMULATE_APP_DATA(chan_alice, 2, "Bridge", "");
717 
718  do_sleep();
719 
720  BRIDGE_ENTER(chan_alice, bridge);
721 
722  ANSWER_CHANNEL(chan_bob);
723  EMULATE_APP_DATA(chan_bob, 2, "Bridge", "");
724  do_sleep();
725 
726  BRIDGE_ENTER(chan_bob, bridge);
727 
728  ANSWER_CHANNEL(chan_charlie);
729  EMULATE_APP_DATA(chan_charlie, 2, "Bridge", "");
730  do_sleep();
731  BRIDGE_ENTER(chan_charlie, bridge);
732 
733  BRIDGE_EXIT(chan_alice, bridge);
734  BRIDGE_EXIT(chan_bob, bridge);
735  BRIDGE_EXIT(chan_charlie, bridge);
736 
737  HANGUP_CHANNEL(chan_alice, AST_CAUSE_NORMAL, "");
738  HANGUP_CHANNEL(chan_bob, AST_CAUSE_NORMAL, "");
739  HANGUP_CHANNEL(chan_charlie, AST_CAUSE_NORMAL, "");
740 
741  return AST_TEST_PASS;
742 }
743 #endif
744 
745 #define EMULATE_DIAL(channel, dialstring) do { \
746  EMULATE_APP_DATA(channel, 1, "Dial", dialstring); \
747  if (append_expected_event(channel, AST_CEL_APP_START, NULL, NULL, NULL)) { \
748  return AST_TEST_FAIL; \
749  } \
750  } while (0)
751 
752 #define START_DIALED(caller, callee) \
753  START_DIALED_FULL(caller, callee, "200", "Bob")
754 
755 #define START_DIALED_FULL(caller, callee, number, name) do { \
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); \
759  if (append_expected_event(callee, AST_CEL_CHANNEL_START, NULL, NULL, NULL)) { \
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)
766 
767 AST_TEST_DEFINE(test_cel_dial_unanswered)
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 }
800 
801 AST_TEST_DEFINE(test_cel_dial_unanswered_filter)
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 }
835 
836 AST_TEST_DEFINE(test_cel_dial_busy)
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 }
869 
870 AST_TEST_DEFINE(test_cel_dial_congestion)
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 }
903 
904 AST_TEST_DEFINE(test_cel_dial_unavailable)
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 }
937 
938 AST_TEST_DEFINE(test_cel_dial_caller_cancel)
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 }
972 
973 AST_TEST_DEFINE(test_cel_dial_parallel_failed)
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 }
1025 
1026 AST_TEST_DEFINE(test_cel_dial_answer_no_bridge)
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 }
1069 
1070 AST_TEST_DEFINE(test_cel_dial_answer_twoparty_bridge_a)
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 }
1116 
1117 AST_TEST_DEFINE(test_cel_dial_answer_twoparty_bridge_b)
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 }
1162 
1163 #ifdef RACEY_TESTS
1164 AST_TEST_DEFINE(test_cel_dial_answer_multiparty)
1165 {
1166  RAII_VAR(struct ast_channel *, chan_alice, NULL, safe_channel_release);
1167  RAII_VAR(struct ast_channel *, chan_bob, NULL, safe_channel_release);
1168  RAII_VAR(struct ast_channel *, chan_charlie, NULL, safe_channel_release);
1169  RAII_VAR(struct ast_channel *, chan_david, NULL, safe_channel_release);
1170  RAII_VAR(struct ast_bridge *, bridge, NULL, safe_bridge_destroy);
1171  struct ast_party_caller alice_caller = ALICE_CALLERID;
1172  struct ast_party_caller charlie_caller = CHARLIE_CALLERID;
1173 
1174  switch (cmd) {
1175  case TEST_INIT:
1176  info->name = __func__;
1177  info->category = TEST_CATEGORY;
1178  info->summary = "Test dialing, answering, and going into a multi-party bridge";
1179  info->description =
1180  "A little tricky to get to do, but possible with some redirects.";
1181  return AST_TEST_NOT_RUN;
1182  case TEST_EXECUTE:
1183  break;
1184  }
1185  bridge = ast_bridge_basic_new();
1186  ast_test_validate(test, bridge != NULL);
1187 
1188  CREATE_ALICE_CHANNEL(chan_alice, &alice_caller);
1189 
1190  EMULATE_DIAL(chan_alice, CHANNEL_TECH_NAME "/Bob");
1191 
1192  START_DIALED(chan_alice, chan_bob);
1193  do_sleep();
1194 
1195  CREATE_CHARLIE_CHANNEL(chan_charlie, &charlie_caller);
1196  do_sleep();
1197  EMULATE_DIAL(chan_charlie, CHANNEL_TECH_NAME "/Bob");
1198  do_sleep();
1199 
1200  START_DIALED_FULL(chan_charlie, chan_david, "400", "David");
1201 
1203  do_sleep();
1205  do_sleep();
1206  ast_channel_publish_dial(chan_alice, chan_bob, NULL, "ANSWER");
1207  do_sleep();
1208  ast_channel_publish_dial(chan_charlie, chan_david, NULL, "ANSWER");
1209  do_sleep();
1210 
1211  ANSWER_NO_APP(chan_alice);
1212  do_sleep();
1213  ANSWER_NO_APP(chan_bob);
1214  do_sleep();
1215  ANSWER_NO_APP(chan_charlie);
1216  do_sleep();
1217  ANSWER_NO_APP(chan_david);
1218  do_sleep();
1219 
1220  do_sleep();
1221  BRIDGE_ENTER(chan_charlie, bridge);
1222  BRIDGE_ENTER(chan_david, bridge);
1223  BRIDGE_ENTER(chan_bob, bridge);
1224  BRIDGE_ENTER(chan_alice, bridge);
1225 
1226  BRIDGE_EXIT(chan_alice, bridge);
1227  BRIDGE_EXIT(chan_bob, bridge);
1228  BRIDGE_EXIT(chan_charlie, bridge);
1229  BRIDGE_EXIT(chan_david, bridge);
1230 
1231  HANGUP_CHANNEL(chan_alice, AST_CAUSE_NORMAL, "ANSWER");
1232  HANGUP_CHANNEL(chan_bob, AST_CAUSE_NORMAL, "");
1233  HANGUP_CHANNEL(chan_charlie, AST_CAUSE_NORMAL, "ANSWER");
1234  HANGUP_CHANNEL(chan_david, AST_CAUSE_NORMAL, "");
1235 
1236  return AST_TEST_PASS;
1237 }
1238 #endif
1239 
1240 AST_TEST_DEFINE(test_cel_blind_transfer)
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;
1289  ast_bridge_publish_blind_transfer(transfer_msg);
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 }
1301 
1302 /* XXX Validation needs to take into account the BRIDGE_EXIT for Alice and the
1303  * ATTENDEDTRANSFER message are not guaranteed to be ordered
1304  */
1305 #ifdef RACEY_TESTS
1306 AST_TEST_DEFINE(test_cel_attended_transfer_bridges_swap)
1307 {
1308  RAII_VAR(struct ast_channel *, chan_alice, NULL, safe_channel_release);
1309  RAII_VAR(struct ast_channel *, chan_bob, NULL, safe_channel_release);
1310  RAII_VAR(struct ast_channel *, chan_charlie, NULL, safe_channel_release);
1311  RAII_VAR(struct ast_channel *, chan_david, NULL, safe_channel_release);
1312  RAII_VAR(struct ast_bridge *, bridge1, NULL, safe_bridge_destroy);
1313  RAII_VAR(struct ast_bridge *, bridge2, NULL, safe_bridge_destroy);
1314  struct ast_party_caller alice_caller = ALICE_CALLERID;
1315  struct ast_party_caller bob_caller = BOB_CALLERID;
1316  struct ast_party_caller charlie_caller = CHARLIE_CALLERID;
1317  struct ast_party_caller david_caller = ALICE_CALLERID;
1318 
1319  switch (cmd) {
1320  case TEST_INIT:
1321  info->name = __func__;
1322  info->category = TEST_CATEGORY;
1323  info->summary = "Test attended transfers between two pairs of bridged parties";
1324  info->description =
1325  "This test creates four channels, places each pair in"
1326  " a bridge, and then attended transfers the bridges"
1327  " together.";
1328  return AST_TEST_NOT_RUN;
1329  case TEST_EXECUTE:
1330  break;
1331  }
1332  /* Create first set of bridged parties */
1333  bridge1 = ast_bridge_basic_new();
1334  ast_test_validate(test, bridge1 != NULL);
1335 
1336  CREATE_ALICE_CHANNEL(chan_alice, &alice_caller);
1337  CREATE_BOB_CHANNEL(chan_bob, &bob_caller);
1338  ANSWER_NO_APP(chan_alice);
1339  ANSWER_NO_APP(chan_bob);
1340 
1341  BRIDGE_ENTER(chan_bob, bridge1);
1342  BRIDGE_ENTER(chan_alice, bridge1);
1343 
1344  /* Create second set of bridged parties */
1345  bridge2 = ast_bridge_basic_new();
1346  ast_test_validate(test, bridge2 != NULL);
1347 
1348  CREATE_DAVID_CHANNEL(chan_david, &david_caller);
1349  CREATE_CHARLIE_CHANNEL(chan_charlie, &charlie_caller);
1350  ANSWER_NO_APP(chan_david);
1351  ANSWER_NO_APP(chan_charlie);
1352 
1353  BRIDGE_ENTER(chan_charlie, bridge2);
1354 
1355  BRIDGE_ENTER(chan_david, bridge2);
1356  BRIDGE_EXIT_EVENT(chan_bob, bridge1);
1357  do_sleep();
1358 
1359  /* Perform attended transfer */
1360  if (ast_bridge_transfer_attended(chan_alice, chan_david)) {
1361  ast_test_status_update(test, "Attended transfer failed!\n");
1362  return AST_TEST_FAIL;
1363  }
1364  do_sleep();
1365  BRIDGE_ENTER_EVENT_PEER(chan_bob, bridge2, "CELTestChannel/David,CELTestChannel/Charlie");
1366 
1367  BRIDGE_EXIT_EVENT(chan_david, bridge2);
1368  BRIDGE_EXIT_EVENT(chan_alice, bridge1);
1369  ATTENDEDTRANSFER_BRIDGE(chan_alice, bridge1, chan_david, bridge2, chan_charlie, chan_bob);
1370 
1371  do_sleep();
1372  BRIDGE_EXIT(chan_bob, bridge2);
1373  BRIDGE_EXIT(chan_charlie, bridge2);
1374 
1375  HANGUP_CHANNEL(chan_alice, AST_CAUSE_NORMAL, "");
1376  do_sleep();
1377  HANGUP_CHANNEL(chan_bob, AST_CAUSE_NORMAL, "");
1378  do_sleep();
1379  HANGUP_CHANNEL(chan_david, AST_CAUSE_NORMAL, "");
1380  do_sleep();
1381  HANGUP_CHANNEL(chan_charlie, AST_CAUSE_NORMAL, "");
1382 
1383  return AST_TEST_PASS;
1384 }
1385 #endif
1386 
1387 AST_TEST_DEFINE(test_cel_attended_transfer_bridges_merge)
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 }
1470 
1471 /* XXX Validation needs to take into account the BRIDGE_EXIT for David and the
1472  * ATTENDEDTRANSFER message are not guaranteed to be ordered
1473  */
1474 #ifdef RACEY_TESTS
1475 AST_TEST_DEFINE(test_cel_attended_transfer_bridges_link)
1476 {
1477  RAII_VAR(struct ast_channel *, chan_alice, NULL, safe_channel_release);
1478  RAII_VAR(struct ast_channel *, chan_bob, NULL, safe_channel_release);
1479  RAII_VAR(struct ast_channel *, chan_charlie, NULL, safe_channel_release);
1480  RAII_VAR(struct ast_channel *, chan_david, NULL, safe_channel_release);
1481  RAII_VAR(struct ast_bridge *, bridge1, NULL, safe_bridge_destroy);
1482  RAII_VAR(struct ast_bridge *, bridge2, NULL, safe_bridge_destroy);
1483  struct ast_party_caller alice_caller = ALICE_CALLERID;
1484  struct ast_party_caller bob_caller = BOB_CALLERID;
1485  struct ast_party_caller charlie_caller = CHARLIE_CALLERID;
1486  struct ast_party_caller david_caller = ALICE_CALLERID;
1487 
1488  switch (cmd) {
1489  case TEST_INIT:
1490  info->name = __func__;
1491  info->category = TEST_CATEGORY;
1492  info->summary = "Test attended transfers between two pairs of"
1493  " bridged parties that results in a bridge merge";
1494  info->description =
1495  "This test creates four channels, places each pair"
1496  " in a bridge, and then attended transfers the bridges"
1497  " together causing a bridge link.";
1498  return AST_TEST_NOT_RUN;
1499  case TEST_EXECUTE:
1500  break;
1501  }
1502  /* Create first set of bridged parties */
1507  "test_cel", "test_cel_atxfer_bridges_link_1", NULL);
1508  ast_test_validate(test, bridge1 != NULL);
1509 
1510  CREATE_ALICE_CHANNEL(chan_alice, &alice_caller);
1511  CREATE_BOB_CHANNEL(chan_bob, &bob_caller);
1512  ANSWER_NO_APP(chan_alice);
1513  ANSWER_NO_APP(chan_bob);
1514 
1515  BRIDGE_ENTER(chan_bob, bridge1);
1516  BRIDGE_ENTER(chan_alice, bridge1);
1517 
1518  /* Create second set of bridged parties */
1523  "test_cel", "test_cel_atxfer_bridges_link_2", NULL);
1524  ast_test_validate(test, bridge2 != NULL);
1525 
1526  CREATE_DAVID_CHANNEL(chan_david, &david_caller);
1527  CREATE_CHARLIE_CHANNEL(chan_charlie, &charlie_caller);
1528  ANSWER_NO_APP(chan_david);
1529  ANSWER_NO_APP(chan_charlie);
1530 
1531  BRIDGE_ENTER(chan_charlie, bridge2);
1532  BRIDGE_ENTER(chan_david, bridge2);
1533 
1534  /* Perform attended transfer */
1535  ATTENDEDTRANSFER_BRIDGE(chan_alice, bridge1, chan_david, bridge2, chan_charlie, chan_bob);
1536 
1537  ast_bridge_transfer_attended(chan_alice, chan_david);
1538  do_sleep();
1539 
1540  /* BRIDGE_EXIT alice and david */
1543 
1544  do_sleep();
1545  BRIDGE_EXIT(chan_bob, bridge1);
1546  BRIDGE_EXIT(chan_charlie, bridge2);
1547 
1548  HANGUP_CHANNEL(chan_alice, AST_CAUSE_NORMAL, "");
1549  do_sleep();
1550  HANGUP_CHANNEL(chan_bob, AST_CAUSE_NORMAL, "");
1551  do_sleep();
1552  HANGUP_CHANNEL(chan_david, AST_CAUSE_NORMAL, "");
1553  do_sleep();
1554  HANGUP_CHANNEL(chan_charlie, AST_CAUSE_NORMAL, "");
1555  do_sleep();
1556 
1557  return AST_TEST_PASS;
1558 }
1559 #endif
1560 
1561 AST_TEST_DEFINE(test_cel_dial_pickup)
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 }
1615 
1616 AST_TEST_DEFINE(test_cel_local_optimize)
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 }
1682 
1683 /*! Container for astobj2 duplicated ast_events */
1685 
1686 /*! Container for expected CEL events */
1688 
1689 static struct ast_event *ao2_dup_event(const struct ast_event *event)
1690 {
1691  struct ast_event *event_dup;
1692  uint16_t event_len;
1693 
1694  event_len = ast_event_get_size(event);
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 }
1705 
1706 static void mid_test_sync(void)
1707 {
1708  ast_mutex_lock(&mid_test_sync_lock);
1709  if (ao2_container_count(cel_expected_events) <= ao2_container_count(cel_received_events)) {
1710  ast_mutex_unlock(&mid_test_sync_lock);
1711  return;
1712  }
1713 
1714  do_mid_test_sync = 1;
1715  ast_mutex_unlock(&mid_test_sync_lock);
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 
1724  SCOPED_MUTEX(lock, &sync_lock);
1725  ast_cond_timedwait(&sync_out, &sync_lock, &end);
1726  }
1727 }
1728 
1729 static int append_event(struct ast_event *ev)
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 
1737  ao2_link(cel_expected_events, ao2_ev);
1738  return 0;
1739 }
1740 
1741 #ifdef RACEY_TESTS
1742 static int append_dummy_event(void)
1743 {
1744  RAII_VAR(struct ast_event *, ev, NULL, ast_free);
1745  RAII_VAR(struct ast_event *, ao2_ev, NULL, ao2_cleanup);
1746 
1748  if (!ev) {
1749  return -1;
1750  }
1751 
1752  return append_event(ev);
1753 }
1754 #endif
1755 
1757  struct ast_channel_snapshot *snapshot,
1758  enum ast_cel_event_type type,
1759  const char *userdefevname,
1760  struct ast_json *extra,
1761  const char *peer)
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 }
1771 
1773  struct ast_channel *chan,
1774  enum ast_cel_event_type type,
1775  const char *userdefevname,
1776  struct ast_json *extra,
1777  const char *peer)
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 }
1789 
1790 static void test_sub(struct ast_event *event)
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) {
1809  int expected = ao2_container_count(cel_expected_events);
1810  int received = ao2_container_count(cel_received_events);
1811  if (expected <= received) {
1812  {
1813  SCOPED_MUTEX(lock, &sync_lock);
1815  do_mid_test_sync = 0;
1816  }
1817  }
1818  }
1819 }
1820 
1821 /*!
1822  * \internal
1823  * \brief Callback function called before each test executes
1824  */
1825 static int test_cel_init_cb(struct ast_test_info *info, struct ast_test *test)
1826 {
1827  ast_assert(cel_received_events == NULL);
1828  ast_assert(cel_expected_events == NULL);
1829 
1830  ast_mutex_init(&mid_test_sync_lock);
1831  ast_mutex_init(&sync_lock);
1833 
1834  /* Back up the real CEL config and insert the test's config */
1835  saved_config = ast_cel_get_config();
1836  ast_cel_set_config(cel_test_config);
1837 
1838  /* init CEL event storage (degenerate hash table becomes a linked list) */
1839  cel_received_events = ao2_container_alloc_list(AO2_ALLOC_OPT_LOCK_MUTEX, 0, NULL, NULL);
1840  cel_expected_events = ao2_container_alloc_list(AO2_ALLOC_OPT_LOCK_MUTEX, 0, NULL, NULL);
1841 
1842  /* start the CEL event callback */
1844  return -1;
1845  }
1846  return 0;
1847 }
1848 
1849 /*!
1850  * \brief Check two peer strings for equality
1851  *
1852  * \retval zero if the peer strings do not match
1853  * \retval non-zero if the peer strings match
1854  */
1855 static int test_cel_peer_strings_match(const char *str1, const char *str2)
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 }
1888 
1889 /*!
1890  * \brief Check an IE value from two events
1891  *
1892  * \retval zero if the IEs in the events of the specified type do not match
1893  * \retval non-zero if the IEs in the events of the specified type match
1894  */
1895 static int match_ie_val(
1896  const struct ast_event *event1,
1897  const struct ast_event *event2,
1898  enum ast_event_ie_type type)
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 }
1947 
1948 static int events_are_equal(struct ast_test *test, struct ast_event *received, struct ast_event *expected)
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 }
1968 
1969 static int dump_event(struct ast_test *test, struct ast_event *event)
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 
2005  ast_test_status_update(test, "\n");
2006 
2007  return 0;
2008 }
2009 
2010 static int check_events(struct ast_test *test, struct ao2_container *local_expected, struct ao2_container *local_received)
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 }
2066 
2067 /*!
2068  * \internal
2069  * \brief Callback function called after each test executes.
2070  *
2071  * \details
2072  * In addition to cleanup, this function also performs verification
2073  * that the events received during a test match the events that were
2074  * expected to have been generated during the test.
2075  */
2076 static int cel_verify_and_cleanup_cb(struct ast_test_info *info, struct ast_test *test)
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);
2080  ast_assert(cel_received_events != NULL);
2081  ast_assert(cel_expected_events != NULL);
2082 
2083  do_sleep();
2084 
2085  /* stop the CEL event callback and clean up storage structures*/
2087 
2088  /* cleaned up by RAII_VAR's */
2089  cel_expected_events = NULL;
2090  cel_received_events = NULL;
2091 
2092  /* check events */
2093  ast_test_validate(test, !check_events(test, local_expected, local_received));
2094 
2095  /* Restore the real CEL config */
2096  ast_cel_set_config(saved_config);
2097  ao2_cleanup(saved_config);
2098  saved_config = NULL;
2099 
2100  /* clean up the locks */
2101  ast_mutex_destroy(&sync_lock);
2102  ast_mutex_destroy(&mid_test_sync_lock);
2104  return 0;
2105 }
2106 
2107 static int unload_module(void)
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 
2144  ast_channel_unregister(&test_cel_chan_tech);
2145 
2146  ao2_cleanup(cel_expected_events);
2147  cel_expected_events = NULL;
2148  ao2_cleanup(cel_received_events);
2149  cel_received_events = NULL;
2150  ao2_cleanup(cel_test_config);
2151  cel_test_config = NULL;
2152 
2153  return 0;
2154 }
2155 
2156 static int load_module(void)
2157 {
2158  /* build the test config */
2159  cel_test_config = ast_cel_general_config_alloc();
2160  if (!cel_test_config) {
2161  return -1;
2162  }
2163  cel_test_config->enable = 1;
2164  if (ast_str_container_add(cel_test_config->apps, "dial")) {
2165  return -1;
2166  }
2167  if (ast_str_container_add(cel_test_config->apps, "park")) {
2168  return -1;
2169  }
2170  if (ast_str_container_add(cel_test_config->apps, "queue")) {
2171  return -1;
2172  }
2173  cel_test_config->events |= 1<<AST_CEL_APP_START;
2174  cel_test_config->events |= 1<<AST_CEL_CHANNEL_START;
2175  cel_test_config->events |= 1<<AST_CEL_CHANNEL_END;
2176  cel_test_config->events |= 1<<AST_CEL_ANSWER;
2177  cel_test_config->events |= 1<<AST_CEL_HANGUP;
2178  cel_test_config->events |= 1<<AST_CEL_BRIDGE_ENTER;
2179  cel_test_config->events |= 1<<AST_CEL_BRIDGE_EXIT;
2180  cel_test_config->events |= 1<<AST_CEL_BLINDTRANSFER;
2181  cel_test_config->events |= 1<<AST_CEL_ATTENDEDTRANSFER;
2182  cel_test_config->events |= 1<<AST_CEL_PICKUP;
2183  cel_test_config->events |= 1<<AST_CEL_LOCAL_OPTIMIZE;
2184 
2185  ast_channel_register(&test_cel_chan_tech);
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 
2228  return AST_MODULE_LOAD_SUCCESS;
2229 }
2230 
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
#define APPEND_EVENT_SNAPSHOT(snapshot, ev_type, userevent, extra, peer)
Definition: test_cel.c:105
Contains all the initialization information required to store a new test definition.
Definition: test.h:221
static const char type[]
Definition: chan_ooh323.c:109
#define ast_channel_lock(chan)
Definition: channel.h:2902
struct ao2_container * channels
Definition: bridge.h:339
Main Channel structure associated with a channel.
Local proxy channel special access.
static void mid_test_sync(void)
Definition: test_cel.c:1706
An event.
Definition: event.c:81
#define AST_MODULE_INFO_STANDARD(keystr, desc)
Definition: module.h:567
const char *const type
Definition: channel.h:630
static int cel_verify_and_cleanup_cb(struct ast_test_info *info, struct ast_test *test)
Definition: test_cel.c:2076
struct ast_channel_snapshot_base * base
Asterisk main include file. File version handling, generic pbx functions.
#define TEST_CATEGORY
Definition: test_cel.c:54
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.
static void do_sleep(void)
Definition: test_cel.c:87
int ao2_container_count(struct ao2_container *c)
Returns the number of elements in a container.
enum ast_transfer_result ast_bridge_transfer_attended(struct ast_channel *to_transferee, struct ast_channel *to_transfer_target)
Attended transfer.
Definition: bridge.c:4729
static struct ast_str * test_cel_generate_peer_str(struct ast_channel *chan, struct ast_bridge *bridge)
Definition: test_cel.c:364
struct ast_json * ast_json_pack(char const *format,...)
Helper for creating complex JSON values.
Definition: json.c:591
#define BRIDGE_ENTER_EVENT_PEER(channel, bridge, peer)
Definition: test_cel.c:161
enum ast_event_type ast_event_get_type(const struct ast_event *event)
Get the type for an event.
Definition: event.c:288
Definition: ast_expr2.c:325
ast_event_ie_pltype
Payload types for event information elements.
Definition: event_defs.h:321
The arg parameter is a search key, but is not an object.
Definition: astobj2.h:1105
Message published during a blind transfer.
Call Event Logging API.
Time-related functions and macros.
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_party_name name
Subscriber name.
Definition: channel.h:341
void ast_channel_unregister(const struct ast_channel_tech *tech)
Unregister a channel technology.
Definition: channel.c:566
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...
static int test_cel_peer_strings_match(const char *str1, const char *str2)
Check two peer strings for equality.
Definition: test_cel.c:1855
#define TEST_BACKEND_NAME
Definition: test_cel.c:58
Channel Variables.
int ast_cel_backend_register(const char *name, ast_cel_backend_cb backend_callback)
Register a CEL backend.
Definition: cel.c:1740
struct ast_channel * ast_channel_release(struct ast_channel *chan)
Unlink and release reference to a channel.
Definition: channel.c:1570
#define BRIDGE_EXIT_EVENT(channel, bridge)
Definition: test_cel.c:123
#define ast_set_flag(p, flag)
Definition: utils.h:70
Call Pickup API.
static int load_module(void)
Definition: test_cel.c:2156
static int unload_module(void)
Definition: test_cel.c:2107
static int debug
Global debug status.
Definition: res_xmpp.c:432
Structure that contains a snapshot of information about a bridge.
Definition: bridge.h:322
Channel Event channel name Used by: AST_EVENT_CEL Payload type: STR.
Definition: event_defs.h:181
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
#define ao2_container_alloc_list(ao2_options, container_options, sort_fn, cmp_fn)
Definition: astobj2.h:1335
A local channel optimization occurred.
Definition: cel.h:77
Structure representing a snapshot of channel state.
Channel Event Time (micro-seconds) Used by: AST_EVENT_CEL Payload type: UINT.
Definition: event_defs.h:145
#define ast_str_container_alloc(buckets)
Allocates a hash container for bare strings.
Definition: strings.h:1312
int ast_do_pickup(struct ast_channel *chan, struct ast_channel *target)
Pickup a call target.
Definition: pickup.c:302
Test Framework API.
channel birth
Definition: cel.h:45
#define AST_TEST_REGISTER(cb)
Definition: test.h:127
char * str
Subscriber name (Malloced)
Definition: channel.h:265
int ast_bridge_destroy(struct ast_bridge *bridge, int cause)
Destroy a bridge.
Definition: bridge.c:970
static struct ast_cel_general_config * cel_test_config
The CEL config used for CEL unit tests.
Definition: test_cel.c:64
static struct ast_cel_general_config * saved_config
A placeholder for Asterisk&#39;s &#39;real&#39; CEL configuration.
Definition: test_cel.c:61
Definition: astman.c:222
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:222
const ast_string_field uniqueid
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:1091
#define ast_cond_init(cond, attr)
Definition: lock.h:199
void ao2_iterator_destroy(struct ao2_iterator *iter)
Destroy a container iterator.
struct timeval ast_tvnow(void)
Returns current timeval. Meant to replace calls to gettimeofday().
Definition: time.h:150
#define ast_assert(a)
Definition: utils.h:650
#define ast_mutex_lock(a)
Definition: lock.h:187
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
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:535
#define ast_strdup(str)
A wrapper for strdup()
Definition: astmm.h:243
supposed to be an opaque type
Definition: event_defs.h:356
#define NULL
Definition: resample.c:96
static struct ast_str * __test_cel_generate_peer_str(struct ast_channel_snapshot *chan, struct ast_bridge_snapshot *bridge)
Definition: test_cel.c:314
static int events_are_equal(struct ast_test *test, struct ast_event *received, struct ast_event *expected)
Definition: test_cel.c:1948
#define ast_cond_signal(cond)
Definition: lock.h:201
static struct timespec to_sleep
A 1 second sleep.
Definition: test_cel.c:85
int64_t events
Definition: cel.h:210
#define APPEND_EVENT(chan, ev_type, userevent, extra)
Definition: test_cel.c:93
Channel Event Type Used by: AST_EVENT_CEL Payload type: UINT.
Definition: event_defs.h:133
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...
static int test_cel_init_cb(struct ast_test_info *info, struct ast_test *test)
Definition: test_cel.c:1825
Utility functions.
char * ast_str_truncate(struct ast_str *buf, ssize_t len)
Truncates the enclosed string to the given length.
Definition: strings.h:738
pthread_cond_t ast_cond_t
Definition: lock.h:176
Channel Event Time (seconds) Used by: AST_EVENT_CEL Payload type: UINT.
Definition: event_defs.h:139
ast_mutex_t sync_lock
Lock used with sync_out for checking the end of test execution.
Definition: test_cel.c:70
const char * ast_cel_get_type_name(enum ast_cel_event_type type)
Get the name of a CEL event type.
Definition: cel.c:491
static struct ast_channel_tech test_cel_chan_tech
A channel technology used for the unit tests.
Definition: test_cel.c:79
struct ast_json * ast_json_null(void)
Get the JSON null value.
Definition: json.c:248
struct ast_party_id id
Caller party ID.
Definition: channel.h:421
void ast_cel_set_config(struct ast_cel_general_config *config)
Set the current CEL configuration.
Definition: cel.c:1702
channel enters a bridge
Definition: cel.h:57
ast_event_ie_type
Event Information Element types.
Definition: event_defs.h:68
struct ast_bridge_snapshot * ast_bridge_get_snapshot(struct ast_bridge *bridge)
Returns the current snapshot for the bridge.
#define SCOPED_CHANNELLOCK(varname, chan)
scoped lock specialization for channels.
Definition: lock.h:617
General Asterisk PBX channel definitions.
static struct ao2_container * cel_received_events
Definition: test_cel.c:1684
Asterisk JSON abstraction layer.
#define SCOPED_MUTEX(varname, lock)
scoped lock specialization for mutexes
Definition: lock.h:587
#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:851
#define ast_test_status_update(a, b, c...)
Definition: test.h:129
static void test_sub(struct ast_event *event)
Definition: test_cel.c:1790
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.
ast_mutex_t lock
Definition: app_meetme.c:1091
Caller Party information.
Definition: channel.h:419
ast_mutex_t mid_test_sync_lock
Lock used for synchronizing test execution stages with received events.
Definition: test_cel.c:67
static int check_events(struct ast_test *test, struct ao2_container *local_expected, struct ao2_container *local_received)
Definition: test_cel.c:2010
#define ALICE_CALLERID
Alice&#39;s Caller ID.
Definition: test_cel.c:196
A set of macros to manage forward-linked lists.
#define CREATE_ALICE_CHANNEL(channel_var, caller_id)
Create a test_cel_chan_tech for Alice.
Definition: test_cel.c:221
hangup terminates connection
Definition: cel.h:49
#define AST_CAUSE_NO_ANSWER
Definition: causes.h:108
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:960
a transfer occurs
Definition: cel.h:65
#define BRIDGE_ENTER(channel, bridge)
Definition: test_cel.c:147
Structure to describe a channel "technology", ie a channel driver See for examples: ...
Definition: channel.h:629
#define APPEND_DUMMY_EVENT()
Definition: test_cel.c:111
int ast_cel_backend_unregister(const char *name)
Unregister a CEL backend.
Definition: cel.c:1728
const char * ast_channel_uniqueid(const struct ast_channel *chan)
#define AST_CAUSE_NORMAL
Definition: causes.h:150
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.
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
Structure that contains information about a bridge.
Definition: bridge.h:357
#define BRIDGE_EXIT(channel, bridge)
Definition: test_cel.c:117
static struct ast_event * ao2_dup_event(const struct ast_event *event)
Definition: test_cel.c:1689
a transfer occurs
Definition: cel.h:67
#define START_DIALED_FULL(caller, callee, number, name)
Definition: test_cel.c:755
The descriptor of a dynamic string XXX storage will be optimized later if needed We use the ts field ...
Definition: strings.h:584
#define ATTENDEDTRANSFER_BRIDGE(channel1, bridge1, channel2, bridge2, channel3, channel4)
Definition: test_cel.c:180
#define CHARLIE_CALLERID
Charlie&#39;s Caller ID.
Definition: test_cel.c:202
#define CHANNEL_TECH_NAME
Definition: test_cel.c:56
#define AST_TEST_UNREGISTER(cb)
Definition: test.h:128
struct stasis_message * stasis_message_create(struct stasis_message_type *type, void *data)
Create a new message.
def info(msg)
int errno
#define ao2_iterator_next(iter)
Definition: astobj2.h:1933
#define ast_cond_destroy(cond)
Definition: lock.h:200
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...
#define ao2_alloc(data_size, destructor_fn)
Definition: astobj2.h:411
#define START_DIALED(caller, callee)
Definition: test_cel.c:752
#define ANSWER_NO_APP(chan)
Definition: test_cel.c:267
struct ao2_container * apps
Definition: cel.h:214
#define ast_channel_unlock(chan)
Definition: channel.h:2903
static struct ast_str * test_cel_generate_peer_str_snapshot(struct ast_channel_snapshot *chan, struct ast_bridge *bridge)
Definition: test_cel.c:351
#define BRIDGE_EXIT_EVENT_PEER(channel, bridge, peer)
Definition: test_cel.c:130
#define ast_bridge_unlock(bridge)
Unlock the bridge.
Definition: bridge.h:493
channel end
Definition: cel.h:47
void stasis_publish(struct stasis_topic *topic, struct stasis_message *message)
Publish a message to a topic&#39;s subscribers.
Definition: stasis.c:1510
#define ast_free(a)
Definition: astmm.h:182
struct ast_cel_general_config * ast_cel_get_config(void)
Obtain the current CEL configuration.
Definition: cel.c:1690
void ast_bridge_publish_blind_transfer(struct ast_blind_transfer_message *transfer_message)
Publish a blind transfer event.
Channel Event Peer – for Things involving multiple channels, like BRIDGE Used by: AST_EVENT_CEL Payl...
Definition: event_defs.h:241
#define ao2_find(container, arg, flags)
Definition: astobj2.h:1756
#define HANGUP_CHANNEL(channel, cause, dialstatus)
Hang up a test channel safely.
Definition: test_cel.c:273
Basic bridge subclass API.
#define ast_clear_flag(p, flag)
Definition: utils.h:77
void ast_channel_exten_set(struct ast_channel *chan, const char *value)
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
uint16_t event_len
Definition: event.c:85
#define ast_bridge_lock(bridge)
Lock the bridge.
Definition: bridge.h:480
ast_cond_t sync_out
Condition used for checking the end of test execution.
Definition: test_cel.c:73
static int dump_event(struct ast_test *test, struct ast_event *event)
Definition: test_cel.c:1969
A structure to hold CEL global configuration options.
Definition: cel.h:205
struct stasis_message_type * ast_local_optimization_begin_type(void)
Message type for when a local channel optimization begins.
struct ast_bridge * ast_bridge_basic_new(void)
Create a new basic class bridge.
int ast_event_iterator_init(struct ast_event_iterator *iterator, const struct ast_event *event)
Initialize an event iterator instance.
Definition: event.c:242
#define BOB_CALLERID
Bob&#39;s Caller ID.
Definition: test_cel.c:199
char * strsep(char **str, const char *delims)
#define AST_CAUSE_NO_ROUTE_DESTINATION
Definition: causes.h:99
int ast_event_iterator_next(struct ast_event_iterator *iterator)
Move iterator instance to next IE.
Definition: event.c:258
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...
When we need to walk through a container, we use an ao2_iterator to keep track of the current positio...
Definition: astobj2.h:1841
#define ao2_cleanup(obj)
Definition: astobj2.h:1958
struct ast_event * ast_event_new(enum ast_event_type event_type,...)
Create a new event.
Definition: event.c:402
void ast_channel_context_set(struct ast_channel *chan, const char *value)
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:269
void * ast_cel_general_config_alloc(void)
Allocate a CEL configuration object.
Definition: cel.c:188
A ringing phone is answered.
Definition: cel.h:51
const char * ast_channel_name(const struct ast_channel *chan)
void ast_channel_state_set(struct ast_channel *chan, enum ast_channel_state)
A multi channel blob data structure for multi_channel_blob stasis messages.
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:208
#define BLINDTRANSFER_EVENT(channel, bridge, extension, context)
Definition: test_cel.c:168
#define AST_CAUSE_BUSY
Definition: causes.h:148
Internal Asterisk hangup causes.
Abstract JSON element (object, array, string, int, ...).
#define CREATE_DAVID_CHANNEL(channel_var, caller_id)
Create a test_cel_chan_tech for David.
Definition: test_cel.c:245
#define CREATE_BOB_CHANNEL(channel_var, caller_id)
Create a test_cel_chan_tech for Bob.
Definition: test_cel.c:229
channel exits a bridge
Definition: cel.h:59
ast_cel_event_type
CEL event types.
Definition: cel.h:41
AST_TEST_DEFINE(test_cel_channel_creation)
Definition: test_cel.c:393
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:274
size_t ast_event_get_size(const struct ast_event *event)
Get the size of an event.
Definition: event.c:228
static void safe_channel_release(struct ast_channel *chan)
Definition: test_cel.c:377
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
#define EMULATE_DIAL(channel, dialstring)
Definition: test_cel.c:745
#define ast_mutex_init(pmutex)
Definition: lock.h:184
Generic container type.
static struct ao2_container * cel_expected_events
Definition: test_cel.c:1687
Call Parking and Pickup API Includes code and algorithms from the Zapata library. ...
struct ast_flags * ast_channel_flags(struct ast_channel *chan)
#define ast_mutex_destroy(a)
Definition: lock.h:186
an app starts
Definition: cel.h:53
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:517
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 void safe_bridge_destroy(struct ast_bridge *bridge)
Definition: test_cel.c:385
#define ASTERISK_GPL_KEY
The text the key() function should return.
Definition: module.h:46
Bridging API.
Asterisk module definitions.
#define EMULATE_APP_DATA(channel, priority, application, data)
Emulate a channel entering into an application.
Definition: test_cel.c:253
#define ANSWER_CHANNEL(chan)
Definition: test_cel.c:262
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:264
a directed pickup was performed on this channel
Definition: cel.h:73
#define CREATE_CHARLIE_CHANNEL(channel_var, caller_id)
Create a test_cel_chan_tech for Charlie.
Definition: test_cel.c:237
struct ao2_iterator ao2_iterator_init(struct ao2_container *c, int flags) attribute_warn_unused_result
Create an iterator for a container.
#define ast_cond_timedwait(cond, mutex, time)
Definition: lock.h:204
static int append_event(struct ast_event *ev)
Definition: test_cel.c:1729
#define AST_CAUSE_CONGESTION
Definition: causes.h:152
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:206
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.
Structure for mutex and tracking information.
Definition: lock.h:135
Media Format Cache API.
#define ast_str_create(init_len)
Create a malloc&#39;ed dynamic length string.
Definition: strings.h:620
#define ast_mutex_unlock(a)
Definition: lock.h:188
#define ao2_link(container, obj)
Definition: astobj2.h:1549