d785ef1f1b9abd124a51565b6e9641df34772197
[asterisk/asterisk.git] / tests / test_cel.c
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 ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
35
36 #include <math.h>
37 #include "asterisk/module.h"
38 #include "asterisk/test.h"
39 #include "asterisk/cel.h"
40 #include "asterisk/channel.h"
41 #include "asterisk/linkedlists.h"
42 #include "asterisk/chanvars.h"
43 #include "asterisk/utils.h"
44 #include "asterisk/causes.h"
45 #include "asterisk/time.h"
46 #include "asterisk/bridging.h"
47 #include "asterisk/bridging_basic.h"
48 #include "asterisk/stasis_channels.h"
49 #include "asterisk/stasis_bridging.h"
50
51 #define TEST_CATEGORY "/main/cel/"
52
53 #define CHANNEL_TECH_NAME "CELTestChannel"
54
55 /*! \brief A placeholder for Asterisk's 'real' CEL configuration */
56 static struct ast_cel_general_config *saved_config;
57
58 /*! \brief The CEL config used for CEL unit tests */
59 static struct ast_cel_general_config *cel_test_config;
60
61 /*! \brief A channel technology used for the unit tests */
62 static struct ast_channel_tech test_cel_chan_tech = {
63         .type = CHANNEL_TECH_NAME,
64         .description = "Mock channel technology for CEL tests",
65 };
66
67 /*! \brief A 1 second sleep */
68 static struct timespec to_sleep = {1, 0};
69
70 static void do_sleep(void)
71 {
72         while ((nanosleep(&to_sleep, &to_sleep) == -1) && (errno == EINTR));
73 }
74
75 #define APPEND_EVENT(chan, ev_type, userevent, extra, peer) do { \
76         if (append_expected_event(chan, ev_type, userevent, extra, peer)) { \
77                 return AST_TEST_FAIL; \
78         } \
79         } while (0)
80
81 /*! \brief Alice's Caller ID */
82 #define ALICE_CALLERID { .id.name.str = "Alice", .id.name.valid = 1, .id.number.str = "100", .id.number.valid = 1, }
83
84 /*! \brief Bob's Caller ID */
85 #define BOB_CALLERID { .id.name.str = "Bob", .id.name.valid = 1, .id.number.str = "200", .id.number.valid = 1, }
86
87 /*! \brief Charlie's Caller ID */
88 #define CHARLIE_CALLERID { .id.name.str = "Charlie", .id.name.valid = 1, .id.number.str = "300", .id.number.valid = 1, }
89
90 /*! \brief David's Caller ID */
91 #define DAVID_CALLERID { .id.name.str = "David", .id.name.valid = 1, .id.number.str = "400", .id.number.valid = 1, }
92
93 /*! \brief Create a \ref test_cel_chan_tech for Alice. */
94 #define CREATE_ALICE_CHANNEL(channel_var, caller_id) do { \
95         (channel_var) = ast_channel_alloc(0, AST_STATE_DOWN, (caller_id)->id.number.str, (caller_id)->id.name.str, "100", "100", "default", NULL, 0, CHANNEL_TECH_NAME "/Alice"); \
96         /*ast_channel_set_caller((channel_var), (caller_id), NULL);*/ \
97         APPEND_EVENT(channel_var, AST_CEL_CHANNEL_START, NULL, NULL, NULL); \
98         } while (0)
99
100 /*! \brief Create a \ref test_cel_chan_tech for Bob. */
101 #define CREATE_BOB_CHANNEL(channel_var, caller_id) do { \
102         (channel_var) = ast_channel_alloc(0, AST_STATE_DOWN, (caller_id)->id.number.str, (caller_id)->id.name.str, "200", "200", "default", NULL, 0, CHANNEL_TECH_NAME "/Bob"); \
103         /*ast_channel_set_caller((channel_var), (caller_id), NULL);*/ \
104         APPEND_EVENT(channel_var, AST_CEL_CHANNEL_START, NULL, NULL, NULL); \
105         } while (0)
106
107 /*! \brief Create a \ref test_cel_chan_tech for Charlie. */
108 #define CREATE_CHARLIE_CHANNEL(channel_var, caller_id) do { \
109         (channel_var) = ast_channel_alloc(0, AST_STATE_DOWN, (caller_id)->id.number.str, (caller_id)->id.name.str, "300", "300", "default", NULL, 0, CHANNEL_TECH_NAME "/Charlie"); \
110         /*ast_channel_set_caller((channel_var), (caller_id), NULL);*/ \
111         APPEND_EVENT(channel_var, AST_CEL_CHANNEL_START, NULL, NULL, NULL); \
112         } while (0)
113
114 /*! \brief Create a \ref test_cel_chan_tech for Charlie. */
115 #define CREATE_DAVID_CHANNEL(channel_var, caller_id) do { \
116         (channel_var) = ast_channel_alloc(0, AST_STATE_DOWN, (caller_id)->id.number.str, (caller_id)->id.name.str, "400", "400", "default", NULL, 0, CHANNEL_TECH_NAME "/David"); \
117         /*ast_channel_set_caller((channel_var), (caller_id), NULL);*/ \
118         APPEND_EVENT(channel_var, AST_CEL_CHANNEL_START, NULL, NULL, NULL); \
119         } while (0)
120
121 /*! \brief Emulate a channel entering into an application */
122 #define EMULATE_APP_DATA(channel, priority, application, data) do { \
123         if ((priority) > 0) { \
124                 ast_channel_priority_set((channel), (priority)); \
125         } \
126         ast_channel_appl_set((channel), (application)); \
127         ast_channel_data_set((channel), (data)); \
128         ast_channel_publish_snapshot((channel)); \
129         } while (0)
130
131 #define ANSWER_CHANNEL(chan) do { \
132         EMULATE_APP_DATA(chan, 1, "Answer", ""); \
133         ANSWER_NO_APP(chan); \
134         } while (0)
135
136 #define ANSWER_NO_APP(chan) do { \
137         ast_setstate(chan, AST_STATE_UP); \
138         APPEND_EVENT(chan, AST_CEL_ANSWER, NULL, NULL, NULL); \
139         } while (0)
140
141 /*! \brief Hang up a test channel safely */
142 #define HANGUP_CHANNEL(channel, cause, hangup_extra) do { \
143         ast_channel_hangupcause_set((channel), (cause)); \
144         ao2_ref(channel, +1); \
145         if (!ast_hangup((channel))) { \
146                 APPEND_EVENT(channel, AST_CEL_HANGUP, NULL, hangup_extra, NULL); \
147                 APPEND_EVENT(channel, AST_CEL_CHANNEL_END, NULL, NULL, NULL); \
148                 ao2_cleanup(stasis_cache_get_extended(ast_channel_topic_all_cached(), \
149                         ast_channel_snapshot_type(), ast_channel_uniqueid(channel), 1)); \
150                 ao2_cleanup(channel); \
151                 channel = NULL; \
152         } else { \
153                 APPEND_EVENT(channel, AST_CEL_HANGUP, NULL, hangup_extra, NULL); \
154                 APPEND_EVENT(channel, AST_CEL_CHANNEL_END, NULL, NULL, NULL); \
155                 ao2_cleanup(stasis_cache_get_extended(ast_channel_topic_all_cached(), \
156                         ast_channel_snapshot_type(), ast_channel_uniqueid(channel), 1)); \
157                 ao2_cleanup(channel); \
158         } \
159         } while (0)
160
161 static int append_expected_event(
162         struct ast_channel *chan,
163         enum ast_cel_event_type type,
164         const char *userdefevname,
165         const char *extra, const char *peer);
166
167 static void safe_channel_release(struct ast_channel *chan)
168 {
169         if (!chan) {
170                 return;
171         }
172         ast_channel_release(chan);
173 }
174
175 AST_TEST_DEFINE(test_cel_channel_creation)
176 {
177         RAII_VAR(struct ast_channel *, chan, NULL, safe_channel_release);
178         struct ast_party_caller caller = ALICE_CALLERID;
179
180         switch (cmd) {
181         case TEST_INIT:
182                 info->name = __func__;
183                 info->category = TEST_CATEGORY;
184                 info->summary = "Test the CEL records created when a channel is created";
185                 info->description =
186                         "Test the CEL records created when a channel is created";
187                 return AST_TEST_NOT_RUN;
188         case TEST_EXECUTE:
189                 break;
190         }
191
192         CREATE_ALICE_CHANNEL(chan, (&caller));
193
194         HANGUP_CHANNEL(chan, AST_CAUSE_NORMAL, "16,,");
195
196         return AST_TEST_PASS;
197 }
198
199 AST_TEST_DEFINE(test_cel_unanswered_inbound_call)
200 {
201         RAII_VAR(struct ast_channel *, chan, NULL, safe_channel_release);
202         struct ast_party_caller caller = ALICE_CALLERID;
203
204         switch (cmd) {
205         case TEST_INIT:
206                 info->name = __func__;
207                 info->category = TEST_CATEGORY;
208                 info->summary = "Test inbound unanswered calls";
209                 info->description =
210                         "Test CEL records for a call that is\n"
211                         "inbound to Asterisk, executes some dialplan, but\n"
212                         "is never answered.\n";
213                 return AST_TEST_NOT_RUN;
214         case TEST_EXECUTE:
215                 break;
216         }
217
218         CREATE_ALICE_CHANNEL(chan, &caller);
219
220         EMULATE_APP_DATA(chan, 1, "Wait", "1");
221
222         HANGUP_CHANNEL(chan, AST_CAUSE_NORMAL, "16,,");
223
224         return AST_TEST_PASS;
225 }
226
227 AST_TEST_DEFINE(test_cel_unanswered_outbound_call)
228 {
229         RAII_VAR(struct ast_channel *, chan, NULL, safe_channel_release);
230         struct ast_party_caller caller = {
231                         .id.name.str = "",
232                         .id.name.valid = 1,
233                         .id.number.str = "",
234                         .id.number.valid = 1, };
235
236         switch (cmd) {
237         case TEST_INIT:
238                 info->name = __func__;
239                 info->category = TEST_CATEGORY;
240                 info->summary = "Test outbound unanswered calls";
241                 info->description =
242                         "Test CEL records for a call that is\n"
243                         "outbound to Asterisk but is never answered.\n";
244                 return AST_TEST_NOT_RUN;
245         case TEST_EXECUTE:
246                 break;
247         }
248
249         CREATE_ALICE_CHANNEL(chan, &caller);
250
251         ast_channel_exten_set(chan, "s");
252         ast_channel_context_set(chan, "default");
253         ast_set_flag(ast_channel_flags(chan), AST_FLAG_ORIGINATED);
254         EMULATE_APP_DATA(chan, 0, "AppDial", "(Outgoing Line)");
255         HANGUP_CHANNEL(chan, AST_CAUSE_NORMAL, "16,,");
256
257         return AST_TEST_PASS;
258 }
259
260 AST_TEST_DEFINE(test_cel_single_party)
261 {
262         RAII_VAR(struct ast_channel *, chan, NULL, safe_channel_release);
263         struct ast_party_caller caller = ALICE_CALLERID;
264
265         switch (cmd) {
266         case TEST_INIT:
267                 info->name = __func__;
268                 info->category = TEST_CATEGORY;
269                 info->summary = "Test CEL for a single party";
270                 info->description =
271                         "Test CEL records for a call that is\n"
272                         "answered, but only involves a single channel\n";
273                 return AST_TEST_NOT_RUN;
274         case TEST_EXECUTE:
275                 break;
276         }
277         CREATE_ALICE_CHANNEL(chan, &caller);
278
279         ANSWER_CHANNEL(chan);
280         EMULATE_APP_DATA(chan, 2, "VoiceMailMain", "1");
281
282         HANGUP_CHANNEL(chan, AST_CAUSE_NORMAL, "16,,");
283
284         return AST_TEST_PASS;
285 }
286
287 AST_TEST_DEFINE(test_cel_single_bridge)
288 {
289         RAII_VAR(struct ast_channel *, chan, NULL, safe_channel_release);
290         RAII_VAR(struct ast_bridge *, bridge, NULL, ao2_cleanup);
291
292         struct ast_party_caller caller = ALICE_CALLERID;
293
294         switch (cmd) {
295         case TEST_INIT:
296                 info->name = __func__;
297                 info->category = TEST_CATEGORY;
298                 info->summary = "Test CEL for a single party entering/leaving a bridge";
299                 info->description =
300                         "Test CEL records for a call that is\n"
301                         "answered, enters a bridge, and leaves it.\n";
302                 return AST_TEST_NOT_RUN;
303         case TEST_EXECUTE:
304                 break;
305         }
306         bridge = ast_bridge_basic_new();
307         ast_test_validate(test, bridge != NULL);
308
309         CREATE_ALICE_CHANNEL(chan, &caller);
310
311         ANSWER_CHANNEL(chan);
312         EMULATE_APP_DATA(chan, 2, "Bridge", "");
313
314         do_sleep();
315         ast_bridge_impart(bridge, chan, NULL, NULL, 0);
316
317         do_sleep();
318
319         ast_bridge_depart(chan);
320
321         HANGUP_CHANNEL(chan, AST_CAUSE_NORMAL, "16,,");
322
323         return AST_TEST_PASS;
324 }
325
326 AST_TEST_DEFINE(test_cel_single_bridge_continue)
327 {
328         RAII_VAR(struct ast_channel *, chan, NULL, safe_channel_release);
329         RAII_VAR(struct ast_bridge *, bridge, NULL, ao2_cleanup);
330         struct ast_party_caller caller = ALICE_CALLERID;
331
332         switch (cmd) {
333         case TEST_INIT:
334                 info->name = __func__;
335                 info->category = TEST_CATEGORY;
336                 info->summary = "Test CEL for a single party entering/leaving a bridge";
337                 info->description =
338                         "Test CEL records for a call that is\n"
339                         "answered, enters a bridge, and leaves it.\n";
340                 return AST_TEST_NOT_RUN;
341         case TEST_EXECUTE:
342                 break;
343         }
344         bridge = ast_bridge_basic_new();
345         ast_test_validate(test, bridge != NULL);
346
347         CREATE_ALICE_CHANNEL(chan, &caller);
348
349         ANSWER_CHANNEL(chan);
350         EMULATE_APP_DATA(chan, 2, "Bridge", "");
351
352         do_sleep();
353         ast_bridge_impart(bridge, chan, NULL, NULL, 0);
354
355         do_sleep();
356
357         ast_bridge_depart(chan);
358
359         EMULATE_APP_DATA(chan, 3, "Wait", "");
360
361         /* And then it hangs up */
362         HANGUP_CHANNEL(chan, AST_CAUSE_NORMAL, "16,,");
363
364         return AST_TEST_PASS;
365 }
366
367 AST_TEST_DEFINE(test_cel_single_twoparty_bridge_a)
368 {
369         RAII_VAR(struct ast_channel *, chan_alice, NULL, safe_channel_release);
370         RAII_VAR(struct ast_channel *, chan_bob, NULL, safe_channel_release);
371         RAII_VAR(struct ast_bridge *, bridge, NULL, ao2_cleanup);
372         struct ast_party_caller caller_alice = ALICE_CALLERID;
373         struct ast_party_caller caller_bob = BOB_CALLERID;
374
375         switch (cmd) {
376         case TEST_INIT:
377                 info->name = __func__;
378                 info->category = TEST_CATEGORY;
379                 info->summary = "Test CEL for a single party entering/leaving a bridge";
380                 info->description =
381                         "Test CEL records for a call that is\n"
382                         "answered, enters a bridge, and leaves it. In this scenario, the\n"
383                         "Party A should answer the bridge first.\n";
384                 return AST_TEST_NOT_RUN;
385         case TEST_EXECUTE:
386                 break;
387         }
388         bridge = ast_bridge_basic_new();
389         ast_test_validate(test, bridge != NULL);
390
391         CREATE_ALICE_CHANNEL(chan_alice, &caller_alice);
392
393         CREATE_BOB_CHANNEL(chan_bob, &caller_bob);
394
395         ANSWER_CHANNEL(chan_alice);
396         EMULATE_APP_DATA(chan_alice, 2, "Bridge", "");
397
398         ast_bridge_impart(bridge, chan_alice, NULL, NULL, 0);
399         do_sleep();
400
401         ANSWER_CHANNEL(chan_bob);
402         EMULATE_APP_DATA(chan_bob, 2, "Bridge", "");
403
404         ast_bridge_impart(bridge, chan_bob, NULL, NULL, 0);
405         do_sleep();
406         APPEND_EVENT(chan_alice, AST_CEL_BRIDGE_START, NULL, NULL, ast_channel_name(chan_bob));
407
408         ast_bridge_depart(chan_alice);
409         ast_bridge_depart(chan_bob);
410         APPEND_EVENT(chan_alice, AST_CEL_BRIDGE_END, NULL, NULL, ast_channel_name(chan_bob));
411
412         HANGUP_CHANNEL(chan_alice, AST_CAUSE_NORMAL, "16,,");
413         HANGUP_CHANNEL(chan_bob, AST_CAUSE_NORMAL, "16,,");
414
415         return AST_TEST_PASS;
416 }
417
418 AST_TEST_DEFINE(test_cel_single_twoparty_bridge_b)
419 {
420         RAII_VAR(struct ast_channel *, chan_alice, NULL, safe_channel_release);
421         RAII_VAR(struct ast_channel *, chan_bob, NULL, safe_channel_release);
422         RAII_VAR(struct ast_bridge *, bridge, NULL, ao2_cleanup);
423         struct ast_party_caller caller_alice = ALICE_CALLERID;
424         struct ast_party_caller caller_bob = BOB_CALLERID;
425
426         switch (cmd) {
427         case TEST_INIT:
428                 info->name = __func__;
429                 info->category = TEST_CATEGORY;
430                 info->summary = "Test CEL for a single party entering/leaving a bridge";
431                 info->description =
432                         "Test CEL records for a call that is\n"
433                         "answered, enters a bridge, and leaves it. In this scenario, the\n"
434                         "Party B should answer the bridge first.\n";
435                 return AST_TEST_NOT_RUN;
436         case TEST_EXECUTE:
437                 break;
438         }
439         bridge = ast_bridge_basic_new();
440         ast_test_validate(test, bridge != NULL);
441
442         CREATE_ALICE_CHANNEL(chan_alice, &caller_alice);
443
444         CREATE_BOB_CHANNEL(chan_bob, &caller_bob);
445
446         ANSWER_CHANNEL(chan_alice);
447         EMULATE_APP_DATA(chan_alice, 2, "Bridge", "");
448
449         ANSWER_CHANNEL(chan_bob);
450         EMULATE_APP_DATA(chan_bob, 2, "Bridge", "");
451         do_sleep();
452
453         ast_bridge_impart(bridge, chan_bob, NULL, NULL, 0);
454         do_sleep();
455
456         ast_bridge_impart(bridge, chan_alice, NULL, NULL, 0);
457         do_sleep();
458         APPEND_EVENT(chan_bob, AST_CEL_BRIDGE_START, NULL, NULL, ast_channel_name(chan_alice));
459
460         ast_bridge_depart(chan_alice);
461         ast_bridge_depart(chan_bob);
462         APPEND_EVENT(chan_bob, AST_CEL_BRIDGE_END, NULL, NULL, ast_channel_name(chan_alice));
463
464         HANGUP_CHANNEL(chan_alice, AST_CAUSE_NORMAL, "16,,");
465         HANGUP_CHANNEL(chan_bob, AST_CAUSE_NORMAL, "16,,");
466
467         return AST_TEST_PASS;
468 }
469
470 AST_TEST_DEFINE(test_cel_single_multiparty_bridge)
471 {
472         RAII_VAR(struct ast_channel *, chan_alice, NULL, safe_channel_release);
473         RAII_VAR(struct ast_channel *, chan_bob, NULL, safe_channel_release);
474         RAII_VAR(struct ast_channel *, chan_charlie, NULL, safe_channel_release);
475         RAII_VAR(struct ast_bridge *, bridge, NULL, ao2_cleanup);
476         struct ast_party_caller caller_alice = ALICE_CALLERID;
477         struct ast_party_caller caller_bob = BOB_CALLERID;
478         struct ast_party_caller caller_charlie = CHARLIE_CALLERID;
479
480         switch (cmd) {
481         case TEST_INIT:
482                 info->name = __func__;
483                 info->category = TEST_CATEGORY;
484                 info->summary = "Test CEL for a single party entering/leaving a multi-party bridge";
485                 info->description =
486                         "Test CEL records for a call that is\n"
487                         "answered, enters a bridge, and leaves it. A total of three\n"
488                         "parties perform this action.\n";
489                 return AST_TEST_NOT_RUN;
490         case TEST_EXECUTE:
491                 break;
492         }
493         bridge = ast_bridge_basic_new();
494         ast_test_validate(test, bridge != NULL);
495
496         CREATE_ALICE_CHANNEL(chan_alice, &caller_alice);
497         CREATE_BOB_CHANNEL(chan_bob, &caller_bob);
498         CREATE_CHARLIE_CHANNEL(chan_charlie, &caller_charlie);
499
500         ANSWER_CHANNEL(chan_alice);
501         EMULATE_APP_DATA(chan_alice, 2, "Bridge", "");
502
503         do_sleep();
504
505         ast_bridge_impart(bridge, chan_alice, NULL, NULL, 0);
506
507         ANSWER_CHANNEL(chan_bob);
508         EMULATE_APP_DATA(chan_bob, 2, "Bridge", "");
509         do_sleep();
510
511         ast_bridge_impart(bridge, chan_bob, NULL, NULL, 0);
512         do_sleep();
513         APPEND_EVENT(chan_alice, AST_CEL_BRIDGE_START, NULL, NULL, ast_channel_name(chan_bob));
514
515         ANSWER_CHANNEL(chan_charlie);
516         EMULATE_APP_DATA(chan_charlie, 2, "Bridge", "");
517         ast_bridge_impart(bridge, chan_charlie, NULL, NULL, 0);
518         do_sleep();
519         APPEND_EVENT(chan_alice, AST_CEL_BRIDGE_TO_CONF, NULL, ast_channel_name(chan_charlie), ast_channel_name(chan_bob));
520
521         ast_bridge_depart(chan_alice);
522         APPEND_EVENT(chan_alice, AST_CEL_CONF_EXIT, NULL, NULL, NULL);
523         ast_bridge_depart(chan_bob);
524         APPEND_EVENT(chan_bob, AST_CEL_CONF_EXIT, NULL, NULL, NULL);
525         ast_bridge_depart(chan_charlie);
526         APPEND_EVENT(chan_charlie, AST_CEL_CONF_EXIT, NULL, NULL, NULL);
527
528         HANGUP_CHANNEL(chan_alice, AST_CAUSE_NORMAL, "16,,");
529         HANGUP_CHANNEL(chan_bob, AST_CAUSE_NORMAL, "16,,");
530         HANGUP_CHANNEL(chan_charlie, AST_CAUSE_NORMAL, "16,,");
531
532         return AST_TEST_PASS;
533 }
534
535 #define EMULATE_DIAL(channel, dialstring) do { \
536         EMULATE_APP_DATA(channel, 1, "Dial", dialstring); \
537         if (append_expected_event(channel, AST_CEL_APP_START, NULL, NULL, NULL)) { \
538                 return AST_TEST_FAIL; \
539         } \
540         } while (0)
541
542 #define START_DIALED(caller, callee) \
543         START_DIALED_FULL(caller, callee, "200", "Bob")
544
545 #define START_DIALED_FULL(caller, callee, number, name) do { \
546         callee = ast_channel_alloc(0, AST_STATE_DOWN, NULL, NULL, number, NULL, NULL, ast_channel_linkedid(caller), 0, CHANNEL_TECH_NAME "/" name); \
547         if (append_expected_event(callee, AST_CEL_CHANNEL_START, NULL, NULL, NULL)) { \
548                 return AST_TEST_FAIL; \
549         } \
550         ast_set_flag(ast_channel_flags(callee), AST_FLAG_OUTGOING); \
551         EMULATE_APP_DATA(callee, 0, "AppDial", "(Outgoing Line)"); \
552         ast_channel_publish_dial(caller, callee, name, NULL); \
553         } while (0)
554
555 AST_TEST_DEFINE(test_cel_dial_unanswered)
556 {
557         RAII_VAR(struct ast_channel *, chan_caller, NULL, safe_channel_release);
558         RAII_VAR(struct ast_channel *, chan_callee, NULL, safe_channel_release);
559         struct ast_party_caller caller = ALICE_CALLERID;
560
561         switch (cmd) {
562         case TEST_INIT:
563                 info->name = __func__;
564                 info->category = TEST_CATEGORY;
565                 info->summary = "Test CEL for a dial that isn't answered";
566                 info->description =
567                         "Test CEL records for a channel that\n"
568                         "performs a dial operation that isn't answered\n";
569                 return AST_TEST_NOT_RUN;
570         case TEST_EXECUTE:
571                 break;
572         }
573
574         CREATE_ALICE_CHANNEL(chan_caller, &caller);
575
576         EMULATE_DIAL(chan_caller, CHANNEL_TECH_NAME "/Bob");
577
578         START_DIALED(chan_caller, chan_callee);
579
580         ast_channel_state_set(chan_caller, AST_STATE_RINGING);
581         ast_channel_publish_dial(chan_caller, chan_callee, NULL, "NOANSWER");
582
583         HANGUP_CHANNEL(chan_caller, AST_CAUSE_NO_ANSWER, "19,,NOANSWER");
584         HANGUP_CHANNEL(chan_callee, AST_CAUSE_NO_ANSWER, "19,,");
585
586         return AST_TEST_PASS;
587 }
588
589
590 AST_TEST_DEFINE(test_cel_dial_busy)
591 {
592         RAII_VAR(struct ast_channel *, chan_caller, NULL, safe_channel_release);
593         RAII_VAR(struct ast_channel *, chan_callee, NULL, safe_channel_release);
594         struct ast_party_caller caller = ALICE_CALLERID;
595
596         switch (cmd) {
597         case TEST_INIT:
598                 info->name = __func__;
599                 info->category = TEST_CATEGORY;
600                 info->summary = "Test CEL for a dial that results in a busy";
601                 info->description =
602                         "Test CEL records for a channel that\n"
603                         "performs a dial operation to an endpoint that's busy\n";
604                 return AST_TEST_NOT_RUN;
605         case TEST_EXECUTE:
606                 break;
607         }
608
609         CREATE_ALICE_CHANNEL(chan_caller, &caller);
610
611         EMULATE_DIAL(chan_caller, CHANNEL_TECH_NAME "/Bob");
612
613         START_DIALED(chan_caller, chan_callee);
614
615         ast_channel_state_set(chan_caller, AST_STATE_RINGING);
616         ast_channel_publish_dial(chan_caller, chan_callee, NULL, "BUSY");
617
618         HANGUP_CHANNEL(chan_caller, AST_CAUSE_BUSY, "17,,BUSY");
619         HANGUP_CHANNEL(chan_callee, AST_CAUSE_BUSY, "17,,");
620
621         return AST_TEST_PASS;
622 }
623
624 AST_TEST_DEFINE(test_cel_dial_congestion)
625 {
626         RAII_VAR(struct ast_channel *, chan_caller, NULL, safe_channel_release);
627         RAII_VAR(struct ast_channel *, chan_callee, NULL, safe_channel_release);
628         struct ast_party_caller caller = ALICE_CALLERID;
629
630         switch (cmd) {
631         case TEST_INIT:
632                 info->name = __func__;
633                 info->category = TEST_CATEGORY;
634                 info->summary = "Test CEL for a dial that results in congestion";
635                 info->description =
636                         "Test CEL records for a channel that\n"
637                         "performs a dial operation to an endpoint that's congested\n";
638                 return AST_TEST_NOT_RUN;
639         case TEST_EXECUTE:
640                 break;
641         }
642
643         CREATE_ALICE_CHANNEL(chan_caller, &caller);
644
645         EMULATE_DIAL(chan_caller, CHANNEL_TECH_NAME "/Bob");
646
647         START_DIALED(chan_caller, chan_callee);
648
649         ast_channel_state_set(chan_caller, AST_STATE_RINGING);
650         ast_channel_publish_dial(chan_caller, chan_callee, NULL, "CONGESTION");
651
652         HANGUP_CHANNEL(chan_caller, AST_CAUSE_CONGESTION, "34,,CONGESTION");
653         HANGUP_CHANNEL(chan_callee, AST_CAUSE_CONGESTION, "34,,");
654
655         return AST_TEST_PASS;
656 }
657
658 AST_TEST_DEFINE(test_cel_dial_unavailable)
659 {
660         RAII_VAR(struct ast_channel *, chan_caller, NULL, safe_channel_release);
661         RAII_VAR(struct ast_channel *, chan_callee, NULL, safe_channel_release);
662         struct ast_party_caller caller = ALICE_CALLERID;
663
664         switch (cmd) {
665         case TEST_INIT:
666                 info->name = __func__;
667                 info->category = TEST_CATEGORY;
668                 info->summary = "Test CEL for a dial that results in unavailable";
669                 info->description =
670                         "Test CEL records for a channel that\n"
671                         "performs a dial operation to an endpoint that's unavailable\n";
672                 return AST_TEST_NOT_RUN;
673         case TEST_EXECUTE:
674                 break;
675         }
676
677         CREATE_ALICE_CHANNEL(chan_caller, &caller);
678
679         EMULATE_DIAL(chan_caller, CHANNEL_TECH_NAME "/Bob");
680
681         START_DIALED(chan_caller, chan_callee);
682
683         ast_channel_state_set(chan_caller, AST_STATE_RINGING);
684         ast_channel_publish_dial(chan_caller, chan_callee, NULL, "CHANUNAVAIL");
685
686         HANGUP_CHANNEL(chan_caller, AST_CAUSE_NO_ROUTE_DESTINATION, "3,,CHANUNAVAIL");
687         HANGUP_CHANNEL(chan_callee, AST_CAUSE_NO_ROUTE_DESTINATION, "3,,");
688
689         return AST_TEST_PASS;
690 }
691
692 AST_TEST_DEFINE(test_cel_dial_caller_cancel)
693 {
694         RAII_VAR(struct ast_channel *, chan_caller, NULL, safe_channel_release);
695         RAII_VAR(struct ast_channel *, chan_callee, NULL, safe_channel_release);
696         struct ast_party_caller caller = ALICE_CALLERID;
697
698         switch (cmd) {
699         case TEST_INIT:
700                 info->name = __func__;
701                 info->category = TEST_CATEGORY;
702                 info->summary = "Test CEL for a dial where the caller cancels";
703                 info->description =
704                         "Test CEL records for a channel that\n"
705                         "performs a dial operation to an endpoint but then decides\n"
706                         "to hang up, cancelling the dial\n";
707                 return AST_TEST_NOT_RUN;
708         case TEST_EXECUTE:
709                 break;
710         }
711
712         CREATE_ALICE_CHANNEL(chan_caller, &caller);
713
714         EMULATE_DIAL(chan_caller, CHANNEL_TECH_NAME "/Bob");
715
716         START_DIALED(chan_caller, chan_callee);
717
718         ast_channel_state_set(chan_caller, AST_STATE_RINGING);
719         ast_channel_publish_dial(chan_caller, chan_callee, NULL, "CANCEL");
720
721         HANGUP_CHANNEL(chan_callee, AST_CAUSE_NORMAL, "16,,");
722         HANGUP_CHANNEL(chan_caller, AST_CAUSE_NORMAL, "16,,CANCEL");
723
724         return AST_TEST_PASS;
725 }
726
727 AST_TEST_DEFINE(test_cel_dial_parallel_failed)
728 {
729         RAII_VAR(struct ast_channel *, chan_caller, NULL, safe_channel_release);
730         RAII_VAR(struct ast_channel *, chan_bob, NULL, safe_channel_release);
731         RAII_VAR(struct ast_channel *, chan_charlie, NULL, safe_channel_release);
732         RAII_VAR(struct ast_channel *, chan_david, NULL, safe_channel_release);
733         struct ast_party_caller caller = ALICE_CALLERID;
734
735         switch (cmd) {
736         case TEST_INIT:
737                 info->name = __func__;
738                 info->category = TEST_CATEGORY;
739                 info->summary = "Test a parallel dial where all channels fail to answer";
740                 info->description =
741                         "This tests dialing three parties: Bob, Charlie, David. Charlie\n"
742                         "returns BUSY; David returns CONGESTION; Bob fails to answer and\n"
743                         "Alice hangs up. Three records are created for Alice as a result.\n";
744                 return AST_TEST_NOT_RUN;
745         case TEST_EXECUTE:
746                 break;
747         }
748
749         CREATE_ALICE_CHANNEL(chan_caller, &caller);
750
751         /* Channel enters Dial app */
752         EMULATE_DIAL(chan_caller, CHANNEL_TECH_NAME "/Bob&" CHANNEL_TECH_NAME "/Charlie&" CHANNEL_TECH_NAME "/David");
753
754         /* Outbound channels are created */
755         START_DIALED_FULL(chan_caller, chan_bob, "200", "Bob");
756         START_DIALED_FULL(chan_caller, chan_charlie, "300", "Charlie");
757         START_DIALED_FULL(chan_caller, chan_david, "400", "David");
758
759         /* Dial starts */
760         ast_channel_state_set(chan_caller, AST_STATE_RINGING);
761
762         /* Charlie is busy */
763         ast_channel_publish_dial(chan_caller, chan_charlie, NULL, "BUSY");
764         HANGUP_CHANNEL(chan_charlie, AST_CAUSE_BUSY, "17,,");
765
766         /* David is congested */
767         ast_channel_publish_dial(chan_caller, chan_david, NULL, "CONGESTION");
768         HANGUP_CHANNEL(chan_david, AST_CAUSE_CONGESTION, "34,,");
769
770         /* Bob is canceled */
771         ast_channel_publish_dial(chan_caller, chan_bob, NULL, "CANCEL");
772         HANGUP_CHANNEL(chan_bob, AST_CAUSE_NORMAL, "16,,");
773
774         /* Alice hangs up */
775         HANGUP_CHANNEL(chan_caller, AST_CAUSE_NORMAL, "16,,BUSY");
776
777         return AST_TEST_PASS;
778 }
779
780 AST_TEST_DEFINE(test_cel_dial_answer_no_bridge)
781 {
782         RAII_VAR(struct ast_channel *, chan_caller, NULL, safe_channel_release);
783         RAII_VAR(struct ast_channel *, chan_callee, NULL, safe_channel_release);
784         struct ast_party_caller caller = ALICE_CALLERID;
785
786         switch (cmd) {
787         case TEST_INIT:
788                 info->name = __func__;
789                 info->category = TEST_CATEGORY;
790                 info->summary = "Test dialing, answering, and not going into a bridge.";
791                 info->description =
792                         "This is a weird one, but theoretically possible. You can perform\n"
793                         "a dial, then bounce both channels to different priorities and\n"
794                         "never have them enter a bridge together. Ew. This makes sure that\n"
795                         "when we answer, we get a CEL, it gets ended at that point, and\n"
796                         "that it gets finalized appropriately.\n";
797                 return AST_TEST_NOT_RUN;
798         case TEST_EXECUTE:
799                 break;
800         }
801
802         CREATE_ALICE_CHANNEL(chan_caller, &caller);
803
804         EMULATE_DIAL(chan_caller, CHANNEL_TECH_NAME "/Bob");
805
806         START_DIALED(chan_caller, chan_callee);
807
808         ast_channel_state_set(chan_caller, AST_STATE_RINGING);
809         ast_channel_publish_dial(chan_caller, chan_callee, NULL, "ANSWER");
810
811         ANSWER_NO_APP(chan_caller);
812         ast_clear_flag(ast_channel_flags(chan_callee), AST_FLAG_OUTGOING);
813         ANSWER_NO_APP(chan_callee);
814
815         EMULATE_APP_DATA(chan_caller, 2, "Wait", "1");
816         EMULATE_APP_DATA(chan_callee, 1, "Wait", "1");
817
818         HANGUP_CHANNEL(chan_caller, AST_CAUSE_NORMAL, "16,,ANSWER");
819         HANGUP_CHANNEL(chan_callee, AST_CAUSE_NORMAL, "16,,");
820
821         return AST_TEST_PASS;
822 }
823
824 AST_TEST_DEFINE(test_cel_dial_answer_twoparty_bridge_a)
825 {
826         RAII_VAR(struct ast_channel *, chan_caller, NULL, safe_channel_release);
827         RAII_VAR(struct ast_channel *, chan_callee, NULL, safe_channel_release);
828         RAII_VAR(struct ast_bridge *, bridge, NULL, ao2_cleanup);
829         struct ast_party_caller caller = ALICE_CALLERID;
830
831         switch (cmd) {
832         case TEST_INIT:
833                 info->name = __func__;
834                 info->category = TEST_CATEGORY;
835                 info->summary = "Test dialing, answering, and going into a 2-party bridge";
836                 info->description =
837                         "The most 'basic' of scenarios\n";
838                 return AST_TEST_NOT_RUN;
839         case TEST_EXECUTE:
840                 break;
841         }
842         bridge = ast_bridge_basic_new();
843         ast_test_validate(test, bridge != NULL);
844
845         CREATE_ALICE_CHANNEL(chan_caller, &caller);
846
847         EMULATE_DIAL(chan_caller, CHANNEL_TECH_NAME "/Bob");
848
849         START_DIALED(chan_caller, chan_callee);
850
851         ast_channel_state_set(chan_caller, AST_STATE_RINGING);
852         ast_channel_publish_dial(chan_caller, chan_callee, NULL, "ANSWER");
853
854         ANSWER_NO_APP(chan_caller);
855         ANSWER_NO_APP(chan_callee);
856
857         do_sleep();
858
859         ast_bridge_impart(bridge, chan_caller, NULL, NULL, 0);
860         do_sleep();
861         ast_bridge_impart(bridge, chan_callee, NULL, NULL, 0);
862         do_sleep();
863         APPEND_EVENT(chan_caller, AST_CEL_BRIDGE_START, NULL, NULL, ast_channel_name(chan_callee));
864
865         ast_bridge_depart(chan_caller);
866         ast_bridge_depart(chan_callee);
867         APPEND_EVENT(chan_caller, AST_CEL_BRIDGE_END, NULL, NULL, ast_channel_name(chan_callee));
868
869         HANGUP_CHANNEL(chan_caller, AST_CAUSE_NORMAL, "16,,ANSWER");
870         HANGUP_CHANNEL(chan_callee, AST_CAUSE_NORMAL, "16,,");
871
872         return AST_TEST_PASS;
873 }
874
875 AST_TEST_DEFINE(test_cel_dial_answer_twoparty_bridge_b)
876 {
877         RAII_VAR(struct ast_channel *, chan_caller, NULL, safe_channel_release);
878         RAII_VAR(struct ast_channel *, chan_callee, NULL, safe_channel_release);
879         RAII_VAR(struct ast_bridge *, bridge, NULL, ao2_cleanup);
880         struct ast_party_caller caller = ALICE_CALLERID;
881
882         switch (cmd) {
883         case TEST_INIT:
884                 info->name = __func__;
885                 info->category = TEST_CATEGORY;
886                 info->summary = "Test dialing, answering, and going into a 2-party bridge";
887                 info->description =
888                         "The most 'basic' of scenarios\n";
889                 return AST_TEST_NOT_RUN;
890         case TEST_EXECUTE:
891                 break;
892         }
893         bridge = ast_bridge_basic_new();
894         ast_test_validate(test, bridge != NULL);
895
896         CREATE_ALICE_CHANNEL(chan_caller, &caller);
897
898         EMULATE_DIAL(chan_caller, CHANNEL_TECH_NAME "/Bob");
899
900         START_DIALED(chan_caller, chan_callee);
901
902         ast_channel_state_set(chan_caller, AST_STATE_RINGING);
903         ast_channel_publish_dial(chan_caller, chan_callee, NULL, "ANSWER");
904
905         ANSWER_NO_APP(chan_caller);
906         ANSWER_NO_APP(chan_callee);
907
908         do_sleep();
909         ast_bridge_impart(bridge, chan_callee, NULL, NULL, 0);
910         do_sleep();
911         ast_bridge_impart(bridge, chan_caller, NULL, NULL, 0);
912         do_sleep();
913         APPEND_EVENT(chan_callee, AST_CEL_BRIDGE_START, NULL, NULL, ast_channel_name(chan_caller));
914
915         ast_bridge_depart(chan_caller);
916         ast_bridge_depart(chan_callee);
917         APPEND_EVENT(chan_callee, AST_CEL_BRIDGE_END, NULL, NULL, ast_channel_name(chan_caller));
918
919         HANGUP_CHANNEL(chan_caller, AST_CAUSE_NORMAL, "16,,ANSWER");
920         HANGUP_CHANNEL(chan_callee, AST_CAUSE_NORMAL, "16,,");
921
922         return AST_TEST_PASS;
923 }
924
925 AST_TEST_DEFINE(test_cel_dial_answer_multiparty)
926 {
927         RAII_VAR(struct ast_channel *, chan_alice, NULL, safe_channel_release);
928         RAII_VAR(struct ast_channel *, chan_bob, NULL, safe_channel_release);
929         RAII_VAR(struct ast_channel *, chan_charlie, NULL, safe_channel_release);
930         RAII_VAR(struct ast_channel *, chan_david, NULL, safe_channel_release);
931         RAII_VAR(struct ast_bridge *, bridge, NULL, ao2_cleanup);
932         struct ast_party_caller alice_caller = ALICE_CALLERID;
933         struct ast_party_caller charlie_caller = CHARLIE_CALLERID;
934
935         switch (cmd) {
936         case TEST_INIT:
937                 info->name = __func__;
938                 info->category = TEST_CATEGORY;
939                 info->summary = "Test dialing, answering, and going into a multi-party bridge";
940                 info->description =
941                         "A little tricky to get to do, but possible with some redirects.\n";
942                 return AST_TEST_NOT_RUN;
943         case TEST_EXECUTE:
944                 break;
945         }
946         bridge = ast_bridge_basic_new();
947         ast_test_validate(test, bridge != NULL);
948
949         CREATE_ALICE_CHANNEL(chan_alice, &alice_caller);
950
951         EMULATE_DIAL(chan_alice, CHANNEL_TECH_NAME "/Bob");
952
953         START_DIALED(chan_alice, chan_bob);
954
955         CREATE_CHARLIE_CHANNEL(chan_charlie, &charlie_caller);
956         EMULATE_DIAL(chan_charlie, CHANNEL_TECH_NAME "/Bob");
957
958         START_DIALED_FULL(chan_charlie, chan_david, "400", "David");
959
960         ast_channel_state_set(chan_alice, AST_STATE_RINGING);
961         ast_channel_state_set(chan_charlie, AST_STATE_RINGING);
962         ast_channel_publish_dial(chan_alice, chan_bob, NULL, "ANSWER");
963         ast_channel_publish_dial(chan_charlie, chan_david, NULL, "ANSWER");
964
965         ANSWER_NO_APP(chan_alice);
966         ANSWER_NO_APP(chan_bob);
967         ANSWER_NO_APP(chan_charlie);
968         ANSWER_NO_APP(chan_david);
969
970         do_sleep();
971         ast_test_validate(test, 0 == ast_bridge_impart(bridge, chan_charlie, NULL, NULL, 0));
972         do_sleep();
973         ast_test_validate(test, 0 == ast_bridge_impart(bridge, chan_david, NULL, NULL, 0));
974         do_sleep();
975         APPEND_EVENT(chan_charlie, AST_CEL_BRIDGE_START, NULL, NULL, ast_channel_name(chan_david));
976
977         ast_test_validate(test, 0 == ast_bridge_impart(bridge, chan_bob, NULL, NULL, 0));
978         do_sleep();
979         APPEND_EVENT(chan_charlie, AST_CEL_BRIDGE_TO_CONF, NULL, ast_channel_name(chan_bob), ast_channel_name(chan_david));
980
981         ast_test_validate(test, 0 == ast_bridge_impart(bridge, chan_alice, NULL, NULL, 0));
982         do_sleep();
983         APPEND_EVENT(chan_alice, AST_CEL_CONF_ENTER, NULL, NULL, NULL);
984
985         ast_test_validate(test, 0 == ast_bridge_depart(chan_alice));
986         APPEND_EVENT(chan_alice, AST_CEL_CONF_EXIT, NULL, NULL, NULL);
987
988         ast_test_validate(test, 0 == ast_bridge_depart(chan_bob));
989         APPEND_EVENT(chan_bob, AST_CEL_CONF_EXIT, NULL, NULL, NULL);
990
991         ast_test_validate(test, 0 == ast_bridge_depart(chan_charlie));
992         APPEND_EVENT(chan_charlie, AST_CEL_CONF_EXIT, NULL, NULL, NULL);
993
994         ast_test_validate(test, 0 == ast_bridge_depart(chan_david));
995         APPEND_EVENT(chan_david, AST_CEL_CONF_EXIT, NULL, NULL, NULL);
996
997         HANGUP_CHANNEL(chan_alice, AST_CAUSE_NORMAL, "16,,ANSWER");
998         HANGUP_CHANNEL(chan_bob, AST_CAUSE_NORMAL, "16,,");
999         HANGUP_CHANNEL(chan_charlie, AST_CAUSE_NORMAL, "16,,ANSWER");
1000         HANGUP_CHANNEL(chan_david, AST_CAUSE_NORMAL, "16,,");
1001
1002         return AST_TEST_PASS;
1003 }
1004
1005 /*! Subscription for CEL events */
1006 static struct ast_event_sub *event_sub = NULL;
1007
1008 /*! Container for astobj2 duplicated ast_events */
1009 static struct ao2_container *cel_received_events = NULL;
1010
1011 /*! Container for expected CEL events */
1012 static struct ao2_container *cel_expected_events = NULL;
1013
1014 static struct ast_event *ao2_dup_event(const struct ast_event *event)
1015 {
1016         struct ast_event *event_dup;
1017         uint16_t event_len;
1018
1019         event_len = ast_event_get_size(event);
1020
1021         event_dup = ao2_alloc(event_len, NULL);
1022         if (!event_dup) {
1023                 return NULL;
1024         }
1025
1026         memcpy(event_dup, event, event_len);
1027
1028         return event_dup;
1029 }
1030
1031 static int append_expected_event(
1032         struct ast_channel *chan,
1033         enum ast_cel_event_type type,
1034         const char *userdefevname,
1035         const char *extra, const char *peer)
1036 {
1037         RAII_VAR(struct ast_channel_snapshot *, snapshot, NULL, ao2_cleanup);
1038         RAII_VAR(struct ast_event *, ev, NULL, ast_free);
1039         RAII_VAR(struct ast_event *, ao2_ev, NULL, ao2_cleanup);
1040         snapshot = ast_channel_snapshot_create(chan);
1041         if (!snapshot) {
1042                 return -1;
1043         }
1044
1045         ev = ast_cel_create_event(snapshot, type, userdefevname, extra, peer);
1046         if (!ev) {
1047                 return -1;
1048         }
1049
1050         ao2_ev = ao2_dup_event(ev);
1051         if (!ao2_ev) {
1052                 return -1;
1053         }
1054
1055         ao2_link(cel_expected_events, ao2_ev);
1056         return 0;
1057 }
1058
1059 ast_mutex_t sync_lock;
1060 ast_cond_t sync_out;
1061
1062 static void test_sub(const struct ast_event *event, void *data)
1063 {
1064         struct ast_event *event_dup = ao2_dup_event(event);
1065         const char *sync_tag;
1066         if (!event_dup) {
1067                 return;
1068         }
1069
1070         sync_tag = ast_event_get_ie_str(event, AST_EVENT_IE_SERVICE);
1071         if (sync_tag) {
1072                 if (!strcmp(sync_tag, "SYNC")) {
1073                         /* trigger things */
1074                         SCOPED_MUTEX(lock, &sync_lock);
1075                         ast_cond_signal(&sync_out);
1076                         return;
1077                 }
1078         }
1079         /* save the event for later processing */
1080         ao2_link(cel_received_events, event_dup);
1081 }
1082
1083 /*!
1084  * \internal \brief Callback function called before each test executes
1085  */
1086 static int test_cel_init_cb(struct ast_test_info *info, struct ast_test *test)
1087 {
1088         ast_assert(event_sub == NULL);
1089         ast_assert(cel_received_events == NULL);
1090         ast_assert(cel_expected_events == NULL);
1091
1092         ast_mutex_init(&sync_lock);
1093         ast_cond_init(&sync_out, NULL);
1094
1095         /* Back up the real CEL config and insert the test's config */
1096         saved_config = ast_cel_get_config();
1097         ast_cel_set_config(cel_test_config);
1098
1099         /* init CEL event storage (degenerate hash table becomes a linked list) */
1100         cel_received_events = ao2_container_alloc(1, NULL, NULL);
1101         cel_expected_events = ao2_container_alloc(1, NULL, NULL);
1102
1103         /* start the CEL event callback */
1104         event_sub = ast_event_subscribe(AST_EVENT_CEL, test_sub, "CEL Test Logging",
1105                 NULL, AST_EVENT_IE_END);
1106         return 0;
1107 }
1108
1109 /*! \brief Check an IE value from two events,  */
1110 static int match_ie_val(
1111         const struct ast_event *event1,
1112         const struct ast_event *event2,
1113         enum ast_event_ie_type type)
1114 {
1115         enum ast_event_ie_pltype pltype = ast_event_get_ie_pltype(type);
1116
1117         switch (pltype) {
1118         case AST_EVENT_IE_PLTYPE_UINT:
1119         {
1120                 uint32_t val = ast_event_get_ie_uint(event2, type);
1121
1122                 return (val == ast_event_get_ie_uint(event1, type)) ? 1 : 0;
1123         }
1124         case AST_EVENT_IE_PLTYPE_STR:
1125         {
1126                 const char *str;
1127                 uint32_t hash;
1128
1129                 hash = ast_event_get_ie_str_hash(event2, type);
1130                 if (hash != ast_event_get_ie_str_hash(event1, type)) {
1131                         return 0;
1132                 }
1133
1134                 str = ast_event_get_ie_str(event2, type);
1135                 if (str) {
1136                         const char *e1str, *e2str;
1137                         e1str = ast_event_get_ie_str(event1, type);
1138                         e2str = str;
1139
1140                         if (type == AST_EVENT_IE_DEVICE) {
1141                                 e1str = ast_tech_to_upper(ast_strdupa(e1str));
1142                                 e2str = ast_tech_to_upper(ast_strdupa(e2str));
1143                         }
1144
1145                         if (!strcmp(e1str, e2str)) {
1146                                 return 1;
1147                         }
1148                 }
1149
1150                 return 0;
1151         }
1152         default:
1153                 break;
1154         }
1155         return 0;
1156 }
1157
1158 static int events_are_equal(struct ast_event *event1, struct ast_event *event2)
1159 {
1160         struct ast_event_iterator iterator;
1161         int res;
1162
1163         for (res = ast_event_iterator_init(&iterator, event1); !res; res = ast_event_iterator_next(&iterator)) {
1164                 /* XXX ignore sec/usec for now */
1165                 /* ignore EID */
1166                 int ie_type = ast_event_iterator_get_ie_type(&iterator);
1167                 if (ie_type != AST_EVENT_IE_CEL_EVENT_TIME_USEC
1168                         && ie_type != AST_EVENT_IE_EID
1169                         && ie_type != AST_EVENT_IE_CEL_EVENT_TIME
1170                         && !match_ie_val(event1, event2, ie_type)) {
1171                         ast_log(LOG_ERROR, "Failed matching on field %s\n", ast_event_get_ie_type_name(ie_type));
1172                         return 0;
1173                 }
1174         }
1175
1176         return 1;
1177 }
1178
1179 static int dump_event(struct ast_event *event)
1180 {
1181         struct ast_event_iterator i;
1182
1183         if (ast_event_iterator_init(&i, event)) {
1184                 ast_log(LOG_ERROR, "Failed to initialize event iterator.  :-(\n");
1185                 return 0;
1186         }
1187
1188         ast_log(LOG_ERROR, "Event: %s %s\n", ast_event_get_type_name(event),
1189                 ast_cel_get_type_name(ast_event_get_ie_uint(event, AST_EVENT_IE_CEL_EVENT_TYPE)));
1190
1191         do {
1192                 enum ast_event_ie_type ie_type;
1193                 enum ast_event_ie_pltype ie_pltype;
1194                 const char *ie_type_name;
1195
1196                 ie_type = ast_event_iterator_get_ie_type(&i);
1197                 ie_type_name = ast_event_get_ie_type_name(ie_type);
1198                 ie_pltype = ast_event_get_ie_pltype(ie_type);
1199
1200                 switch (ie_pltype) {
1201                 case AST_EVENT_IE_PLTYPE_UNKNOWN:
1202                 case AST_EVENT_IE_PLTYPE_EXISTS:
1203                         ast_log(LOG_ERROR, "%s\n", ie_type_name);
1204                         break;
1205                 case AST_EVENT_IE_PLTYPE_STR:
1206                         ast_log(LOG_ERROR, "%.30s: %s\n", ie_type_name,
1207                                         ast_event_iterator_get_ie_str(&i));
1208                         break;
1209                 case AST_EVENT_IE_PLTYPE_UINT:
1210                         ast_log(LOG_ERROR, "%.30s: %u\n", ie_type_name,
1211                                         ast_event_iterator_get_ie_uint(&i));
1212                         break;
1213                 case AST_EVENT_IE_PLTYPE_BITFLAGS:
1214                         ast_log(LOG_ERROR, "%.30s: %u\n", ie_type_name,
1215                                         ast_event_iterator_get_ie_bitflags(&i));
1216                 default:
1217                         break;
1218                 }
1219         } while (!ast_event_iterator_next(&i));
1220
1221         ast_log(LOG_ERROR, "\n");
1222
1223         return 0;
1224 }
1225
1226 static int check_events(struct ao2_container *local_expected, struct ao2_container *local_received)
1227 {
1228         struct ao2_iterator expected_it, received_it;
1229         struct ast_event *rx_event, *ex_event;
1230         int debug = 0;
1231
1232         if (ao2_container_count(local_expected) != ao2_container_count(local_received)) {
1233                 ast_log(LOG_ERROR, "Increasing verbosity since the number of expected events (%d)"
1234                         " did not match number of received events (%d).\n",
1235                         ao2_container_count(local_expected),
1236                         ao2_container_count(local_received));
1237                 debug = 1;
1238         }
1239
1240         expected_it = ao2_iterator_init(local_expected, 0);
1241         received_it = ao2_iterator_init(local_received, 0);
1242         rx_event = ao2_iterator_next(&received_it);
1243         ex_event = ao2_iterator_next(&expected_it);
1244         while (rx_event && ex_event) {
1245                 if (!events_are_equal(rx_event, ex_event)) {
1246                         ast_log(LOG_ERROR, "Received event:\n");
1247                         dump_event(rx_event);
1248                         ast_log(LOG_ERROR, "Expected event:\n");
1249                         dump_event(ex_event);
1250                         return -1;
1251                 }
1252                 if (debug) {
1253                         ast_log(LOG_ERROR, "Compared events successfully\n");
1254                         dump_event(ex_event);
1255                 }
1256                 ao2_cleanup(rx_event);
1257                 ao2_cleanup(ex_event);
1258                 rx_event = ao2_iterator_next(&received_it);
1259                 ex_event = ao2_iterator_next(&expected_it);
1260         }
1261
1262         if (rx_event) {
1263                 ast_log(LOG_ERROR, "Received event:\n");
1264                 dump_event(rx_event);
1265                 ao2_cleanup(rx_event);
1266                 return -1;
1267         }
1268         if (ex_event) {
1269                 ast_log(LOG_ERROR, "Expected event:\n");
1270                 dump_event(ex_event);
1271                 ao2_cleanup(ex_event);
1272                 return -1;
1273         }
1274         return 0;
1275 }
1276
1277 static struct ast_event *create_sync_event(void)
1278 {
1279         struct ast_event *event_dup;
1280         RAII_VAR(struct ast_event *, event, ao2_callback(cel_expected_events, 0, NULL, NULL), ao2_cleanup);
1281         uint16_t event_len;
1282
1283         if (!event) {
1284                 return NULL;
1285         }
1286
1287         event_len = ast_event_get_size(event);
1288
1289         event_dup = ast_calloc(1, event_len);
1290         if (!event_dup) {
1291                 return NULL;
1292         }
1293
1294         memcpy(event_dup, event, event_len);
1295         ast_event_append_ie_str(&event_dup, AST_EVENT_IE_SERVICE, "SYNC");
1296
1297         return event_dup;
1298 }
1299
1300 /*!
1301  * \internal \brief Callback function called after each test executes.
1302  * In addition to cleanup, this function also performs verification
1303  * that the events received during a test match the events that were
1304  * expected to have been generated during the test.
1305  */
1306 static int cel_verify_and_cleanup_cb(struct ast_test_info *info, struct ast_test *test)
1307 {
1308         struct ast_event *sync;
1309         RAII_VAR(struct ao2_container *, local_expected, cel_expected_events, ao2_cleanup);
1310         RAII_VAR(struct ao2_container *, local_received, cel_received_events, ao2_cleanup);
1311         ast_assert(event_sub != NULL);
1312         ast_assert(cel_received_events != NULL);
1313         ast_assert(cel_expected_events != NULL);
1314
1315         do_sleep();
1316
1317         /* sync with the event system */
1318         sync = create_sync_event();
1319         ast_test_validate(test, sync != NULL);
1320         if (ast_event_queue(sync)) {
1321                 ast_event_destroy(sync);
1322                 ast_test_validate(test, NULL);
1323         } else {
1324                 struct timeval start = ast_tvnow();
1325                 struct timespec end = {
1326                         .tv_sec = start.tv_sec + 30,
1327                         .tv_nsec = start.tv_usec * 1000
1328                 };
1329
1330                 SCOPED_MUTEX(lock, &sync_lock);
1331                 ast_cond_timedwait(&sync_out, &sync_lock, &end);
1332         }
1333
1334         /* stop the CEL event callback and clean up storage structures*/
1335         ast_event_unsubscribe(event_sub);
1336         event_sub = NULL;
1337
1338         /* cleaned up by RAII_VAR's */
1339         cel_expected_events = NULL;
1340         cel_received_events = NULL;
1341
1342         /* check events */
1343         ast_test_validate(test, !check_events(local_expected, local_received));
1344
1345         /* Restore the real CEL config */
1346         ast_cel_set_config(saved_config);
1347         ao2_cleanup(saved_config);
1348         saved_config = NULL;
1349
1350         /* clean up the locks */
1351         ast_mutex_destroy(&sync_lock);
1352         ast_cond_destroy(&sync_out);
1353         return 0;
1354 }
1355
1356 static int unload_module(void)
1357 {
1358         AST_TEST_UNREGISTER(test_cel_channel_creation);
1359         AST_TEST_UNREGISTER(test_cel_unanswered_inbound_call);
1360         AST_TEST_UNREGISTER(test_cel_unanswered_outbound_call);
1361         AST_TEST_UNREGISTER(test_cel_single_party);
1362         AST_TEST_UNREGISTER(test_cel_single_bridge);
1363         AST_TEST_UNREGISTER(test_cel_single_bridge_continue);
1364         AST_TEST_UNREGISTER(test_cel_single_twoparty_bridge_a);
1365         AST_TEST_UNREGISTER(test_cel_single_twoparty_bridge_b);
1366         AST_TEST_UNREGISTER(test_cel_single_multiparty_bridge);
1367
1368         AST_TEST_UNREGISTER(test_cel_dial_unanswered);
1369         AST_TEST_UNREGISTER(test_cel_dial_congestion);
1370         AST_TEST_UNREGISTER(test_cel_dial_busy);
1371         AST_TEST_UNREGISTER(test_cel_dial_unavailable);
1372         AST_TEST_UNREGISTER(test_cel_dial_caller_cancel);
1373         AST_TEST_UNREGISTER(test_cel_dial_parallel_failed);
1374         AST_TEST_UNREGISTER(test_cel_dial_answer_no_bridge);
1375         AST_TEST_UNREGISTER(test_cel_dial_answer_twoparty_bridge_a);
1376         AST_TEST_UNREGISTER(test_cel_dial_answer_twoparty_bridge_b);
1377         AST_TEST_UNREGISTER(test_cel_dial_answer_multiparty);
1378
1379         ast_channel_unregister(&test_cel_chan_tech);
1380
1381         ao2_cleanup(cel_test_config);
1382         cel_test_config = NULL;
1383
1384         return 0;
1385 }
1386
1387 static int load_module(void)
1388 {
1389         /* build the test config */
1390         cel_test_config = ast_cel_general_config_alloc();
1391         if (!cel_test_config) {
1392                 return -1;
1393         }
1394         cel_test_config->enable = 1;
1395         if (ast_str_container_add(cel_test_config->apps, "dial")) {
1396                 return -1;
1397         }
1398         if (ast_str_container_add(cel_test_config->apps, "park")) {
1399                 return -1;
1400         }
1401         if (ast_str_container_add(cel_test_config->apps, "queue")) {
1402                 return -1;
1403         }
1404         cel_test_config->events |= 1<<AST_CEL_APP_START;
1405         cel_test_config->events |= 1<<AST_CEL_CHANNEL_START;
1406         cel_test_config->events |= 1<<AST_CEL_CHANNEL_END;
1407         cel_test_config->events |= 1<<AST_CEL_ANSWER;
1408         cel_test_config->events |= 1<<AST_CEL_HANGUP;
1409         cel_test_config->events |= 1<<AST_CEL_BRIDGE_START;
1410         cel_test_config->events |= 1<<AST_CEL_BRIDGE_END;
1411         cel_test_config->events |= 1<<AST_CEL_BRIDGE_TO_CONF;
1412         cel_test_config->events |= 1<<AST_CEL_CONF_ENTER;
1413         cel_test_config->events |= 1<<AST_CEL_CONF_EXIT;
1414
1415         ast_channel_register(&test_cel_chan_tech);
1416
1417         AST_TEST_REGISTER(test_cel_channel_creation);
1418         AST_TEST_REGISTER(test_cel_unanswered_inbound_call);
1419         AST_TEST_REGISTER(test_cel_unanswered_outbound_call);
1420
1421         AST_TEST_REGISTER(test_cel_single_party);
1422         AST_TEST_REGISTER(test_cel_single_bridge);
1423         AST_TEST_REGISTER(test_cel_single_bridge_continue);
1424         AST_TEST_REGISTER(test_cel_single_twoparty_bridge_a);
1425         AST_TEST_REGISTER(test_cel_single_twoparty_bridge_b);
1426         AST_TEST_REGISTER(test_cel_single_multiparty_bridge);
1427
1428         AST_TEST_REGISTER(test_cel_dial_unanswered);
1429         AST_TEST_REGISTER(test_cel_dial_congestion);
1430         AST_TEST_REGISTER(test_cel_dial_busy);
1431         AST_TEST_REGISTER(test_cel_dial_unavailable);
1432         AST_TEST_REGISTER(test_cel_dial_caller_cancel);
1433         AST_TEST_REGISTER(test_cel_dial_parallel_failed);
1434         AST_TEST_REGISTER(test_cel_dial_answer_no_bridge);
1435         AST_TEST_REGISTER(test_cel_dial_answer_twoparty_bridge_a);
1436         AST_TEST_REGISTER(test_cel_dial_answer_twoparty_bridge_b);
1437         AST_TEST_REGISTER(test_cel_dial_answer_multiparty);
1438
1439         /* ast_test_register_* has to happen after AST_TEST_REGISTER */
1440         /* Verify received vs expected events and clean things up after every test */
1441         ast_test_register_init(TEST_CATEGORY, test_cel_init_cb);
1442         ast_test_register_cleanup(TEST_CATEGORY, cel_verify_and_cleanup_cb);
1443
1444         return AST_MODULE_LOAD_SUCCESS;
1445 }
1446
1447 AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "CEL unit tests");