Merge "doc/lang/language-criteria.txt: Link to wiki."
[asterisk/asterisk.git] / tests / test_message.c
1 /*
2  * Asterisk -- An open source telephony toolkit.
3  *
4  * Copyright (C) 2014, Digium, Inc.
5  *
6  * Matt Jordan <mjordan@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 /*! \file
20  *
21  * \brief Test module for out-of-call text message module
22  *
23  * \author \verbatim Matt Jordan <mjordan@digium.com> \endverbatim
24  *
25  * \ingroup tests
26  */
27
28 /*** MODULEINFO
29         <depend>TEST_FRAMEWORK</depend>
30         <support_level>core</support_level>
31  ***/
32
33 #include "asterisk.h"
34
35 #include <regex.h>
36
37 #include "asterisk/module.h"
38 #include "asterisk/test.h"
39 #include "asterisk/message.h"
40 #include "asterisk/pbx.h"
41 #include "asterisk/manager.h"
42 #include "asterisk/vector.h"
43
44 #define TEST_CATEGORY "/main/message/"
45
46 #define TEST_CONTEXT "__TEST_MESSAGE_CONTEXT__"
47 #define TEST_EXTENSION "test_message_extension"
48
49 /*! \brief The number of user events we should get in a dialplan test */
50 #define DEFAULT_EXPECTED_EVENTS 4
51
52 /*! \brief The current number of received user events */
53 static int received_user_events;
54
55 /*! \brief The number of user events we expect for this test */
56 static int expected_user_events;
57
58 /*! \brief Predicate for the \ref test_message_handler receiving a message */
59 static int handler_received_message;
60
61 /*! \brief Condition wait variable for all dialplan user events being received */
62 static ast_cond_t user_event_cond;
63
64 /*! \brief Mutex for \c user_event_cond */
65 AST_MUTEX_DEFINE_STATIC(user_event_lock);
66
67 /*! \brief Condition wait variable for \ref test_msg_handler receiving message */
68 static ast_cond_t handler_cond;
69
70 /*! \brief Mutex for \c handler_cond */
71 AST_MUTEX_DEFINE_STATIC(handler_lock);
72
73 /*! \brief The expected user event fields */
74 AST_VECTOR(var_vector, struct ast_variable *) expected_user_event_fields;
75
76 /*! \brief If a user event fails, the bad headers that didn't match */
77 AST_VECTOR(, struct ast_variable *) bad_headers;
78
79 static int test_msg_send(const struct ast_msg *msg, const char *to, const char *from);
80
81 static struct ast_msg_tech test_msg_tech = {
82         .name = "testmsg",
83         .msg_send = test_msg_send,
84 };
85
86 static int test_msg_handle_msg_cb(struct ast_msg *msg);
87 static int test_msg_has_destination_cb(const struct ast_msg *msg);
88
89 /*! \brief Our test message handler */
90 static struct ast_msg_handler test_msg_handler = {
91         .name = "testmsg",
92         .handle_msg = test_msg_handle_msg_cb,
93         .has_destination = test_msg_has_destination_cb,
94 };
95
96 static int user_event_hook_cb(int category, const char *event, char *body);
97
98 /*! \brief AMI event hook that verifies whether or not we've gotten our user events */
99 static struct manager_custom_hook user_event_hook = {
100         .file = AST_MODULE,
101         .helper = user_event_hook_cb,
102 };
103
104 /*!
105  * \brief Verifies a user event header/value pair
106  *
107  * \param user_event which user event to check
108  * \param header The header to verify
109  * \param value The value read from the event
110  *
111  * \retval -1 on error or evaluation failure
112  * \retval 0 if match not needed or success
113  */
114 static int verify_user_event_fields(int user_event, const char *header, const char *value)
115 {
116         struct ast_variable *current;
117         struct ast_variable *expected;
118         regex_t regexbuf;
119         int error;
120
121         if (user_event >= AST_VECTOR_SIZE(&expected_user_event_fields)) {
122                 return -1;
123         }
124
125         expected = AST_VECTOR_GET(&expected_user_event_fields, user_event);
126         if (!expected) {
127                 return -1;
128         }
129
130         for (current = expected; current; current = current->next) {
131                 struct ast_variable *bad_header;
132
133                 if (strcmp(current->name, header)) {
134                         continue;
135                 }
136
137                 error = regcomp(&regexbuf, current->value, REG_EXTENDED | REG_NOSUB);
138                 if (error) {
139                         char error_buf[128];
140                         regerror(error, &regexbuf, error_buf, sizeof(error_buf));
141                         ast_log(LOG_ERROR, "Failed to compile regex '%s' for header check '%s': %s\n",
142                                 current->value, current->name, error_buf);
143                         return -1;
144                 }
145
146                 if (!regexec(&regexbuf, value, 0, NULL, 0)) {
147                         regfree(&regexbuf);
148                         return 0;
149                 }
150
151                 bad_header = ast_variable_new(header, value, __FILE__);
152                 if (bad_header) {
153                         struct ast_variable *bad_headers_head = NULL;
154
155                         if (user_event < AST_VECTOR_SIZE(&bad_headers)) {
156                                 bad_headers_head = AST_VECTOR_GET(&bad_headers, user_event);
157                         }
158                         ast_variable_list_append(&bad_headers_head, bad_header);
159                         AST_VECTOR_REPLACE(&bad_headers, user_event, bad_headers_head);
160                 }
161                 regfree(&regexbuf);
162                 return -1;
163         }
164
165         return 0;
166 }
167
168 static int message_received;
169
170 static int test_msg_send(const struct ast_msg *msg, const char *to, const char *from)
171 {
172         message_received = 1;
173
174         return 0;
175 }
176
177 static int test_msg_handle_msg_cb(struct ast_msg *msg)
178 {
179         ast_mutex_lock(&handler_lock);
180         handler_received_message = 1;
181         ast_cond_signal(&handler_cond);
182         ast_mutex_unlock(&handler_lock);
183
184         return 0;
185 }
186
187 static int test_msg_has_destination_cb(const struct ast_msg *msg)
188 {
189         /* We only care about one destination: foo! */
190         if (ast_strlen_zero(ast_msg_get_to(msg))) {
191                 return 0;
192         }
193         return (!strcmp(ast_msg_get_to(msg), "foo") ? 1 : 0);
194 }
195
196 static int user_event_hook_cb(int category, const char *event, char *body)
197 {
198         char *parse;
199         char *kvp;
200
201         if (strcmp(event, "UserEvent")) {
202                 return -1;
203         }
204
205         parse = ast_strdupa(body);
206         while ((kvp = strsep(&parse, "\r\n"))) {
207                 char *key, *value;
208
209                 kvp = ast_trim_blanks(kvp);
210                 if (ast_strlen_zero(kvp)) {
211                         continue;
212                 }
213                 key = strsep(&kvp, ":");
214                 value = ast_skip_blanks(kvp);
215                 verify_user_event_fields(received_user_events, key, value);
216         }
217
218         received_user_events++;
219
220         ast_mutex_lock(&user_event_lock);
221         if (received_user_events == expected_user_events) {
222                 ast_cond_signal(&user_event_cond);
223         }
224         ast_mutex_unlock(&user_event_lock);
225
226         return 0;
227 }
228
229 /*! \brief Wait for the \ref test_msg_handler to receive the message */
230 static int handler_wait_for_message(struct ast_test *test)
231 {
232         int error = 0;
233         struct timeval wait = ast_tvadd(ast_tvnow(), ast_tv(5 /* seconds */, 0));
234         struct timespec wait_time = { .tv_sec = wait.tv_sec, .tv_nsec = wait.tv_usec * 1000 };
235
236         ast_mutex_lock(&handler_lock);
237         while (!handler_received_message) {
238                 error = ast_cond_timedwait(&handler_cond, &handler_lock, &wait_time);
239                 if (error == ETIMEDOUT) {
240                         ast_test_status_update(test, "Test timed out while waiting for handler to get message\n");
241                         ast_test_set_result(test, AST_TEST_FAIL);
242                         break;
243                 }
244         }
245         ast_mutex_unlock(&handler_lock);
246
247         return (error != ETIMEDOUT);
248 }
249
250 /*! \brief Wait for the expected number of user events to be received */
251 static int user_event_wait_for_events(struct ast_test *test, int expected_events)
252 {
253         int error;
254         struct timeval wait = ast_tvadd(ast_tvnow(), ast_tv(5 /* seconds */, 0));
255         struct timespec wait_time = { .tv_sec = wait.tv_sec, .tv_nsec = wait.tv_usec * 1000 };
256
257         expected_user_events = expected_events;
258
259         ast_mutex_lock(&user_event_lock);
260         while (received_user_events != expected_user_events) {
261                 error = ast_cond_timedwait(&user_event_cond, &user_event_lock, &wait_time);
262                 if (error == ETIMEDOUT) {
263                         ast_test_status_update(test, "Test timed out while waiting for %d expected user events\n", expected_events);
264                         ast_test_set_result(test, AST_TEST_FAIL);
265                         break;
266                 }
267         }
268         ast_mutex_unlock(&user_event_lock);
269
270         ast_test_status_update(test, "Received %d of %d user events\n", received_user_events, expected_events);
271         return !(received_user_events == expected_events);
272 }
273
274 static int verify_bad_headers(struct ast_test *test)
275 {
276         int res = 0;
277         int i;
278
279         for (i = 0; i < AST_VECTOR_SIZE(&bad_headers); i++) {
280                 struct ast_variable *headers;
281                 struct ast_variable *current;
282
283                 headers = AST_VECTOR_GET(&bad_headers, i);
284                 if (!headers) {
285                         continue;
286                 }
287
288                 res = -1;
289                 for (current = headers; current; current = current->next) {
290                         ast_test_status_update(test, "Expected UserEvent %d: Failed to match %s: %s\n",
291                                 i, current->name, current->value);
292                         ast_test_set_result(test, AST_TEST_FAIL);
293                 }
294         }
295
296         return res;
297 }
298
299 AST_TEST_DEFINE(test_message_msg_tech_registration)
300 {
301         int reg_result;
302
303         switch (cmd) {
304         case TEST_INIT:
305                 info->name = __func__;
306                 info->category = TEST_CATEGORY;
307                 info->summary = "Test register/unregister of a message tech";
308                 info->description =
309                         "Test that:\n"
310                         "\tA message technology can be registered once only\n"
311                         "\tA registered message technology can be unregistered once only";
312                 return AST_TEST_NOT_RUN;
313         case TEST_EXECUTE:
314                 break;
315         }
316
317         reg_result = ast_msg_tech_register(&test_msg_tech);
318         ast_test_validate(test, reg_result == 0);
319
320         reg_result = ast_msg_tech_register(&test_msg_tech);
321         ast_test_validate(test, reg_result == -1);
322
323         reg_result = ast_msg_tech_unregister(&test_msg_tech);
324         ast_test_validate(test, reg_result == 0);
325
326         reg_result = ast_msg_tech_unregister(&test_msg_tech);
327         ast_test_validate(test, reg_result == -1);
328
329         return AST_TEST_PASS;
330 }
331
332 AST_TEST_DEFINE(test_message_msg_handler_registration)
333 {
334         int reg_result;
335
336         switch (cmd) {
337         case TEST_INIT:
338                 info->name = __func__;
339                 info->category = TEST_CATEGORY;
340                 info->summary = "Test register/unregister of a message handler";
341                 info->description =
342                         "Test that:\n"
343                         "\tA message handler can be registered once only\n"
344                         "\tA registered message handler can be unregistered once only";
345                 return AST_TEST_NOT_RUN;
346         case TEST_EXECUTE:
347                 break;
348         }
349
350         reg_result = ast_msg_handler_register(&test_msg_handler);
351         ast_test_validate(test, reg_result == 0);
352
353         reg_result = ast_msg_handler_register(&test_msg_handler);
354         ast_test_validate(test, reg_result == -1);
355
356         reg_result = ast_msg_handler_unregister(&test_msg_handler);
357         ast_test_validate(test, reg_result == 0);
358
359         reg_result = ast_msg_handler_unregister(&test_msg_handler);
360         ast_test_validate(test, reg_result == -1);
361
362         return AST_TEST_PASS;
363 }
364
365 static void ast_msg_safe_destroy(void *obj)
366 {
367         struct ast_msg *msg = obj;
368
369         if (msg) {
370                 ast_msg_destroy(msg);
371         }
372 }
373
374 AST_TEST_DEFINE(test_message_manipulation)
375 {
376         RAII_VAR(struct ast_msg *, msg, NULL, ast_msg_safe_destroy);
377         RAII_VAR(struct ast_msg_var_iterator *, it_vars, NULL, ast_msg_var_iterator_destroy);
378         int result;
379         const char *actual;
380         const char *out_name;
381         const char *out_value;
382
383         switch (cmd) {
384         case TEST_INIT:
385                 info->name = __func__;
386                 info->category = TEST_CATEGORY;
387                 info->summary = "Test manipulating properties of a message";
388                 info->description =
389                         "This test covers the following:\n"
390                         "\tSetting/getting the body\n"
391                         "\tSetting/getting inbound/outbound variables\n"
392                         "\tIterating over variables";
393                 return AST_TEST_NOT_RUN;
394         case TEST_EXECUTE:
395                 break;
396         }
397
398         msg = ast_msg_alloc();
399         ast_test_validate(test, msg != NULL);
400
401         /* Test setting/getting to */
402         result = ast_msg_set_to(msg, "testmsg:%s", "foo");
403         ast_test_validate(test, result == 0);
404         actual = ast_msg_get_to(msg);
405         ast_test_validate(test, !strcmp(actual, "testmsg:foo"));
406
407         /* Test setting/getting from */
408         result = ast_msg_set_from(msg, "testmsg:%s", "bar");
409         ast_test_validate(test, result == 0);
410         actual = ast_msg_get_from(msg);
411         ast_test_validate(test, !strcmp(actual, "testmsg:bar"));
412
413         /* Test setting/getting body */
414         result = ast_msg_set_body(msg, "BodyTest: %s", "foo");
415         ast_test_validate(test, result == 0);
416         actual = ast_msg_get_body(msg);
417         ast_test_validate(test, !strcmp(actual, "BodyTest: foo"));
418
419         /* Test setting/getting technology */
420         result = ast_msg_set_tech(msg, "%s", "my_tech");
421         ast_test_validate(test, result == 0);
422         actual = ast_msg_get_tech(msg);
423         ast_test_validate(test, !strcmp(actual, "my_tech"));
424
425         /* Test setting/getting endpoint */
426         result = ast_msg_set_endpoint(msg, "%s", "terminus");
427         ast_test_validate(test, result == 0);
428         actual = ast_msg_get_endpoint(msg);
429         ast_test_validate(test, !strcmp(actual, "terminus"));
430
431         /* Test setting/getting non-outbound variable */
432         result = ast_msg_set_var(msg, "foo", "bar");
433         ast_test_validate(test, result == 0);
434         actual = ast_msg_get_var(msg, "foo");
435         ast_test_validate(test, !strcmp(actual, "bar"));
436
437         /* Test updating existing variable */
438         result = ast_msg_set_var(msg, "foo", "new_bar");
439         ast_test_validate(test, result == 0);
440         actual = ast_msg_get_var(msg, "foo");
441         ast_test_validate(test, !strcmp(actual, "new_bar"));
442
443         /* Verify a non-outbound variable is not iterable */
444         it_vars = ast_msg_var_iterator_init(msg);
445         ast_test_validate(test, it_vars != NULL);
446         ast_test_validate(test, ast_msg_var_iterator_next(msg, it_vars, &out_name, &out_value) == 0);
447         ast_msg_var_iterator_destroy(it_vars);
448
449         /* Test updating an existing variable as an outbound variable */
450         result = ast_msg_set_var_outbound(msg, "foo", "outbound_bar");
451         ast_test_validate(test, result == 0);
452         it_vars = ast_msg_var_iterator_init(msg);
453         ast_test_validate(test, it_vars != NULL);
454         result = ast_msg_var_iterator_next(msg, it_vars, &out_name, &out_value);
455         ast_test_validate(test, result == 1);
456         ast_test_validate(test, !strcmp(out_name, "foo"));
457         ast_test_validate(test, !strcmp(out_value, "outbound_bar"));
458         ast_msg_var_unref_current(it_vars);
459         result = ast_msg_var_iterator_next(msg, it_vars, &out_name, &out_value);
460         ast_test_validate(test, result == 0);
461
462         return AST_TEST_PASS;
463 }
464
465 AST_TEST_DEFINE(test_message_queue_dialplan_nominal)
466 {
467         RAII_VAR(struct ast_msg *, msg, NULL, ast_msg_safe_destroy);
468         struct ast_variable *expected;
469         struct ast_variable *expected_response = NULL;
470
471         switch (cmd) {
472         case TEST_INIT:
473                 info->name = __func__;
474                 info->category = TEST_CATEGORY;
475                 info->summary = "Test enqueueing messages to the dialplan";
476                 info->description =
477                         "Test that a message enqueued for the dialplan is\n"
478                         "passed to that particular extension";
479                 return AST_TEST_NOT_RUN;
480         case TEST_EXECUTE:
481                 break;
482         }
483
484         msg = ast_msg_alloc();
485         ast_test_validate(test, msg != NULL);
486
487         expected = ast_variable_new("Verify","^To$", __FILE__);
488         ast_variable_list_append(&expected_response, expected);
489         expected = ast_variable_new("Value","^foo$", __FILE__);
490         ast_variable_list_append(&expected_response, expected);
491         AST_VECTOR_REPLACE(&expected_user_event_fields, 0, expected_response);
492
493         expected_response = NULL;
494         expected = ast_variable_new("Verify", "^From$", __FILE__);
495         ast_variable_list_append(&expected_response, expected);
496         expected = ast_variable_new("Value","^bar$", __FILE__);
497         ast_variable_list_append(&expected_response, expected);
498         AST_VECTOR_REPLACE(&expected_user_event_fields, 1, expected_response);
499
500         expected_response = NULL;
501         expected = ast_variable_new("Verify", "^Body$", __FILE__);
502         ast_variable_list_append(&expected_response, expected);
503         expected = ast_variable_new("Value", "^a body$", __FILE__);
504         ast_variable_list_append(&expected_response, expected);
505         AST_VECTOR_REPLACE(&expected_user_event_fields, 2, expected_response);
506
507         expected_response = NULL;
508         expected = ast_variable_new("Verify", "^Custom$", __FILE__);
509         ast_variable_list_append(&expected_response, expected);
510         expected = ast_variable_new("Value", "^field$", __FILE__);
511         ast_variable_list_append(&expected_response, expected);
512         AST_VECTOR_REPLACE(&expected_user_event_fields, 3, expected_response);
513
514         ast_msg_set_to(msg, "foo");
515         ast_msg_set_from(msg, "bar");
516         ast_msg_set_body(msg, "a body");
517         ast_msg_set_var_outbound(msg, "custom_data", "field");
518
519         ast_msg_set_context(msg, TEST_CONTEXT);
520         ast_msg_set_exten(msg, TEST_EXTENSION);
521
522         ast_msg_queue(msg);
523         msg = NULL;
524
525         if (user_event_wait_for_events(test, DEFAULT_EXPECTED_EVENTS)) {
526                 ast_test_status_update(test, "Failed to received %d expected user events\n", DEFAULT_EXPECTED_EVENTS);
527                 return AST_TEST_FAIL;
528         }
529
530         if (verify_bad_headers(test)) {
531                 return AST_TEST_FAIL;
532         }
533
534         return AST_TEST_PASS;
535 }
536
537 AST_TEST_DEFINE(test_message_queue_handler_nominal)
538 {
539         RAII_VAR(struct ast_msg *, msg, NULL, ast_msg_safe_destroy);
540         int result;
541
542         switch (cmd) {
543         case TEST_INIT:
544                 info->name = __func__;
545                 info->category = TEST_CATEGORY;
546                 info->summary = "Test enqueueing messages to a handler";
547                 info->description =
548                         "Test that a message enqueued can be handled by a\n"
549                         "non-dialplan handler";
550                 return AST_TEST_NOT_RUN;
551         case TEST_EXECUTE:
552                 break;
553         }
554
555         msg = ast_msg_alloc();
556         ast_test_validate(test, msg != NULL);
557
558         result = ast_msg_handler_register(&test_msg_handler);
559         ast_test_validate(test, result == 0);
560
561         ast_msg_set_to(msg, "foo");
562         ast_msg_set_from(msg, "bar");
563         ast_msg_set_body(msg, "a body");
564
565         ast_msg_queue(msg);
566         msg = NULL;
567
568         /* This will automatically fail the test if we don't get the message */
569         handler_wait_for_message(test);
570
571         result = ast_msg_handler_unregister(&test_msg_handler);
572         ast_test_validate(test, result == 0);
573
574         return AST_TEST_PASS;
575 }
576
577 AST_TEST_DEFINE(test_message_queue_both_nominal)
578 {
579         RAII_VAR(struct ast_msg *, msg, NULL, ast_msg_safe_destroy);
580         struct ast_variable *expected;
581         struct ast_variable *expected_response = NULL;
582         int result;
583
584         switch (cmd) {
585         case TEST_INIT:
586                 info->name = __func__;
587                 info->category = TEST_CATEGORY;
588                 info->summary = "Test enqueueing messages to a dialplan and custom handler";
589                 info->description =
590                         "Test that a message enqueued is passed to all\n"
591                         "handlers that can process it, dialplan as well as\n"
592                         "a custom handler";
593                 return AST_TEST_NOT_RUN;
594         case TEST_EXECUTE:
595                 break;
596         }
597
598         msg = ast_msg_alloc();
599         ast_test_validate(test, msg != NULL);
600
601         result = ast_msg_handler_register(&test_msg_handler);
602         ast_test_validate(test, result == 0);
603
604         expected = ast_variable_new("Verify","^To$", __FILE__);
605         ast_variable_list_append(&expected_response, expected);
606         expected = ast_variable_new("Value","^foo$", __FILE__);
607         ast_variable_list_append(&expected_response, expected);
608         AST_VECTOR_REPLACE(&expected_user_event_fields, 0, expected_response);
609
610         expected_response = NULL;
611         expected = ast_variable_new("Verify", "^From$", __FILE__);
612         ast_variable_list_append(&expected_response, expected);
613         expected = ast_variable_new("Value","^bar$", __FILE__);
614         ast_variable_list_append(&expected_response, expected);
615         AST_VECTOR_REPLACE(&expected_user_event_fields, 1, expected_response);
616
617         expected_response = NULL;
618         expected = ast_variable_new("Verify", "^Body$", __FILE__);
619         ast_variable_list_append(&expected_response, expected);
620         expected = ast_variable_new("Value", "^a body$", __FILE__);
621         ast_variable_list_append(&expected_response, expected);
622         AST_VECTOR_REPLACE(&expected_user_event_fields, 2, expected_response);
623
624         ast_msg_set_to(msg, "foo");
625         ast_msg_set_from(msg, "bar");
626         ast_msg_set_body(msg, "a body");
627
628         ast_msg_set_context(msg, TEST_CONTEXT);
629         ast_msg_set_exten(msg, TEST_EXTENSION);
630
631         ast_msg_queue(msg);
632         msg = NULL;
633
634         if (user_event_wait_for_events(test, DEFAULT_EXPECTED_EVENTS)) {
635                 ast_test_status_update(test, "Failed to received %d expected user events\n", DEFAULT_EXPECTED_EVENTS);
636                 ast_test_set_result(test, AST_TEST_FAIL);
637         }
638
639         /* This will automatically fail the test if we don't get the message */
640         handler_wait_for_message(test);
641
642         result = ast_msg_handler_unregister(&test_msg_handler);
643         ast_test_validate(test, result == 0);
644
645         if (verify_bad_headers(test)) {
646                 return AST_TEST_FAIL;
647         }
648
649         return AST_TEST_PASS;
650 }
651
652 AST_TEST_DEFINE(test_message_has_destination_dialplan)
653 {
654         RAII_VAR(struct ast_msg *, msg, NULL, ast_msg_safe_destroy);
655
656         switch (cmd) {
657         case TEST_INIT:
658                 info->name = __func__;
659                 info->category = TEST_CATEGORY;
660                 info->summary = "Test checking for a dialplan destination";
661                 info->description =
662                         "Test that a message's destination is verified via the\n"
663                         "dialplan";
664                 return AST_TEST_NOT_RUN;
665         case TEST_EXECUTE:
666                 break;
667         }
668
669         msg = ast_msg_alloc();
670         ast_test_validate(test, msg != NULL);
671
672         ast_msg_set_context(msg, TEST_CONTEXT);
673         ast_msg_set_exten(msg, TEST_EXTENSION);
674         ast_test_validate(test, ast_msg_has_destination(msg) == 1);
675
676         ast_msg_set_context(msg, "__I_SHOULD_NOT_EXIST_PLZ__");
677         ast_test_validate(test, ast_msg_has_destination(msg) == 0);
678
679         ast_msg_set_context(msg, TEST_CONTEXT);
680         ast_msg_set_exten(msg, "__I_SHOULD_NOT_EXIST_PLZ__");
681         ast_test_validate(test, ast_msg_has_destination(msg) == 0);
682
683         ast_msg_set_exten(msg, NULL);
684         ast_test_validate(test, ast_msg_has_destination(msg) == 0);
685
686         ast_msg_set_context(msg, NULL);
687         ast_msg_set_exten(msg, TEST_EXTENSION);
688         ast_test_validate(test, ast_msg_has_destination(msg) == 0);
689
690         return AST_TEST_PASS;
691 }
692
693 AST_TEST_DEFINE(test_message_has_destination_handler)
694 {
695         RAII_VAR(struct ast_msg *, msg, NULL, ast_msg_safe_destroy);
696         int result;
697
698         switch (cmd) {
699         case TEST_INIT:
700                 info->name = __func__;
701                 info->category = TEST_CATEGORY;
702                 info->summary = "Test checking for a handler destination";
703                 info->description =
704                         "Test that a message's destination is verified via a\n"
705                         "handler";
706                 return AST_TEST_NOT_RUN;
707         case TEST_EXECUTE:
708                 break;
709         }
710
711         result = ast_msg_handler_register(&test_msg_handler);
712         ast_test_validate(test, result == 0);
713
714         msg = ast_msg_alloc();
715         ast_test_validate(test, msg != NULL);
716
717         ast_msg_set_to(msg, "foo");
718         ast_msg_set_context(msg, TEST_CONTEXT);
719         ast_msg_set_exten(msg, NULL);
720         ast_test_validate(test, ast_msg_has_destination(msg) == 1);
721
722         ast_msg_set_context(msg, NULL);
723         ast_test_validate(test, ast_msg_has_destination(msg) == 1);
724
725         ast_msg_set_to(msg, "__I_SHOULD_NOT_EXIST_PLZ__");
726         ast_test_validate(test, ast_msg_has_destination(msg) == 0);
727
728         result = ast_msg_handler_unregister(&test_msg_handler);
729         ast_test_validate(test, result == 0);
730
731         return AST_TEST_PASS;
732 }
733
734 AST_TEST_DEFINE(test_message_msg_send)
735 {
736         RAII_VAR(struct ast_msg *, msg, NULL, ast_msg_safe_destroy);
737
738         switch (cmd) {
739         case TEST_INIT:
740                 info->name = __func__;
741                 info->category = TEST_CATEGORY;
742                 info->summary = "Test message routing";
743                 info->description =
744                         "Test that a message can be routed if it has\n"
745                         "a valid handler";
746                 return AST_TEST_NOT_RUN;
747         case TEST_EXECUTE:
748                 break;
749         }
750
751         ast_test_validate(test, ast_msg_tech_register(&test_msg_tech) == 0);
752         ast_test_validate(test, ast_msg_handler_register(&test_msg_handler) == 0);
753
754         msg = ast_msg_alloc();
755         ast_test_validate(test, msg != NULL);
756
757         ast_msg_set_to(msg, "foo");
758         ast_msg_set_context(msg, TEST_CONTEXT);
759         ast_msg_set_exten(msg, NULL);
760         ast_test_validate(test, ast_msg_has_destination(msg) == 1);
761
762         if (!ast_msg_send(msg, "testmsg:foo", "blah")) {
763                 msg = NULL;
764         } else {
765                 ast_test_status_update(test, "Failed to send message\n");
766                 ast_test_set_result(test, AST_TEST_FAIL);
767         }
768
769         ast_test_validate(test, ast_msg_handler_unregister(&test_msg_handler) == 0);
770         ast_test_validate(test, ast_msg_tech_unregister(&test_msg_tech) == 0);
771
772         return AST_TEST_PASS;
773 }
774
775 static int test_init_cb(struct ast_test_info *info, struct ast_test *test)
776 {
777         received_user_events = 0;
778         handler_received_message = 0;
779         message_received = 0;
780
781         AST_VECTOR_INIT(&expected_user_event_fields, DEFAULT_EXPECTED_EVENTS);
782         AST_VECTOR_INIT(&bad_headers, DEFAULT_EXPECTED_EVENTS);
783
784         return 0;
785 }
786
787 #define FREE_VARIABLE_VECTOR(vector) do { \
788         int i; \
789         for (i = 0; i < AST_VECTOR_SIZE(&(vector)); i++) { \
790                 struct ast_variable *headers; \
791                 headers = AST_VECTOR_GET(&(vector), i); \
792                 if (!headers) { \
793                         continue; \
794                 } \
795                 ast_variables_destroy(headers); \
796         } \
797         AST_VECTOR_FREE(&(vector)); \
798         } while (0)
799
800
801 static int test_cleanup_cb(struct ast_test_info *info, struct ast_test *test)
802 {
803         FREE_VARIABLE_VECTOR(expected_user_event_fields);
804         FREE_VARIABLE_VECTOR(bad_headers);
805
806         return 0;
807 }
808
809 static int unload_module(void)
810 {
811         AST_TEST_UNREGISTER(test_message_msg_tech_registration);
812         AST_TEST_UNREGISTER(test_message_msg_handler_registration);
813         AST_TEST_UNREGISTER(test_message_manipulation);
814         AST_TEST_UNREGISTER(test_message_queue_dialplan_nominal);
815         AST_TEST_UNREGISTER(test_message_queue_handler_nominal);
816         AST_TEST_UNREGISTER(test_message_queue_both_nominal);
817         AST_TEST_UNREGISTER(test_message_has_destination_dialplan);
818         AST_TEST_UNREGISTER(test_message_has_destination_handler);
819         AST_TEST_UNREGISTER(test_message_msg_send);
820
821         ast_context_destroy(NULL, AST_MODULE);
822
823         ast_manager_unregister_hook(&user_event_hook);
824
825         return 0;
826 }
827
828 static int create_test_dialplan(void)
829 {
830         int res = 0;
831
832         if (!ast_context_find_or_create(NULL, NULL, TEST_CONTEXT, AST_MODULE)) {
833                 return -1;
834         }
835
836         res |= ast_add_extension(TEST_CONTEXT, 0, TEST_EXTENSION, 1, NULL, NULL,
837                                  "UserEvent", "TestMessageUnitTest,Verify:To,Value:${MESSAGE(to)}",
838                                  NULL, AST_MODULE);
839         res |= ast_add_extension(TEST_CONTEXT, 0, TEST_EXTENSION, 2, NULL, NULL,
840                                  "UserEvent", "TestMessageUnitTest,Verify:From,Value:${MESSAGE(from)}",
841                                  NULL, AST_MODULE);
842         res |= ast_add_extension(TEST_CONTEXT, 0, TEST_EXTENSION, 3, NULL, NULL,
843                                  "UserEvent", "TestMessageUnitTest,Verify:Body,Value:${MESSAGE(body)}",
844                                  NULL, AST_MODULE);
845         res |= ast_add_extension(TEST_CONTEXT, 0, TEST_EXTENSION, 4, NULL, NULL,
846                                  "UserEvent", "TestMessageUnitTest,Verify:Custom,Value:${MESSAGE_DATA(custom_data)}",
847                                  NULL, AST_MODULE);
848         res |= ast_add_extension(TEST_CONTEXT, 0, TEST_EXTENSION, 5, NULL, NULL,
849                                  "Set", "MESSAGE_DATA(custom_data)=${MESSAGE_DATA(custom_data)}",
850                                  NULL, AST_MODULE);
851         res |= ast_add_extension(TEST_CONTEXT, 0, TEST_EXTENSION, 6, NULL, NULL,
852                                  "MessageSend", "testmsg:${MESSAGE(from)},testmsg:${MESSAGE(to)}",
853                                  NULL, AST_MODULE);
854
855         ast_manager_register_hook(&user_event_hook);
856
857         return res;
858 }
859
860 static int load_module(void)
861 {
862         AST_TEST_REGISTER(test_message_msg_tech_registration);
863         AST_TEST_REGISTER(test_message_msg_handler_registration);
864         AST_TEST_REGISTER(test_message_manipulation);
865         AST_TEST_REGISTER(test_message_queue_dialplan_nominal);
866         AST_TEST_REGISTER(test_message_queue_handler_nominal);
867         AST_TEST_REGISTER(test_message_queue_both_nominal);
868         AST_TEST_REGISTER(test_message_has_destination_dialplan);
869         AST_TEST_REGISTER(test_message_has_destination_handler);
870         AST_TEST_REGISTER(test_message_msg_send);
871
872         create_test_dialplan();
873
874         ast_test_register_init(TEST_CATEGORY, test_init_cb);
875         ast_test_register_cleanup(TEST_CATEGORY, test_cleanup_cb);
876
877         return AST_MODULE_LOAD_SUCCESS;
878 }
879
880
881 AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "Out-of-call text message support");