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