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