Merge "core: Tweak startup order."
[asterisk/asterisk.git] / tests / test_res_stasis.c
1 /*
2  * Asterisk -- An open source telephony toolkit.
3  *
4  * Copyright (C) 2013, Digium, Inc.
5  *
6  * David M. Lee, II <dlee@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 Test Stasis Application API.
22  * \author\verbatim David M. Lee, II <dlee@digium.com> \endverbatim
23  *
24  * \ingroup tests
25  */
26
27 /*** MODULEINFO
28         <depend>TEST_FRAMEWORK</depend>
29         <depend>res_stasis</depend>
30         <support_level>core</support_level>
31  ***/
32
33 #include "asterisk.h"
34
35 #include "asterisk/module.h"
36 #include "asterisk/test.h"
37 #include "asterisk/stasis_app.h"
38
39 static const char *test_category = "/stasis/res/";
40
41 AST_TEST_DEFINE(app_invoke_dne)
42 {
43         int res;
44
45         switch (cmd) {
46         case TEST_INIT:
47                 info->name = __func__;
48                 info->category = test_category;
49                 info->summary = "Test stasis app invocation.";
50                 info->description = "Test stasis app invocation.";
51                 return AST_TEST_NOT_RUN;
52         case TEST_EXECUTE:
53                 break;
54         }
55
56         res = stasis_app_send("i-am-not-an-app", ast_json_null());
57         ast_test_validate(test, -1 == res);
58
59         return AST_TEST_PASS;
60 }
61
62 struct app_data {
63         int invocations;
64         struct ast_json *messages;
65 };
66
67 static void app_data_dtor(void *obj)
68 {
69         struct app_data *actual = obj;
70
71         ast_json_unref(actual->messages);
72         actual->messages = NULL;
73 }
74
75 static struct app_data *app_data_create(void)
76 {
77         struct app_data *res = ao2_alloc(sizeof(struct app_data), app_data_dtor);
78
79         if (!res) {
80                 return NULL;
81         }
82
83         res->messages = ast_json_array_create();
84         return res;
85 }
86
87 static void test_handler(void *data, const char *app_name, struct ast_json *message)
88 {
89         struct app_data *actual = data;
90         int res;
91         ++(actual->invocations);
92         res = ast_json_array_append(actual->messages, ast_json_copy(message));
93         ast_assert(res == 0);
94 }
95
96 AST_TEST_DEFINE(app_invoke_one)
97 {
98         RAII_VAR(struct app_data *, app_data, NULL, ao2_cleanup);
99         RAII_VAR(char *, app_name, NULL, stasis_app_unregister);
100         RAII_VAR(struct ast_json *, expected_message, NULL, ast_json_unref);
101         RAII_VAR(struct ast_json *, message, NULL, ast_json_unref);
102         int res;
103
104         switch (cmd) {
105         case TEST_INIT:
106                 info->name = __func__;
107                 info->category = test_category;
108                 info->summary = "Test stasis app invocation.";
109                 info->description = "Test stasis app invocation.";
110                 return AST_TEST_NOT_RUN;
111         case TEST_EXECUTE:
112                 break;
113         }
114
115         app_name = "test-handler";
116
117         app_data = app_data_create();
118
119         stasis_app_register(app_name, test_handler, app_data);
120         message = ast_json_pack("{ s: o }", "test-message", ast_json_null());
121         expected_message = ast_json_pack("[o]", ast_json_ref(message));
122
123         res = stasis_app_send(app_name, message);
124         ast_test_validate(test, 0 == res);
125         ast_test_validate(test, 1 == app_data->invocations);
126         ast_test_validate(test, ast_json_equal(expected_message, app_data->messages));
127
128         return AST_TEST_PASS;
129 }
130
131 AST_TEST_DEFINE(app_replaced)
132 {
133         RAII_VAR(struct app_data *, app_data1, NULL, ao2_cleanup);
134         RAII_VAR(struct app_data *, app_data2, NULL, ao2_cleanup);
135         RAII_VAR(char *, app_name, NULL, stasis_app_unregister);
136         RAII_VAR(struct ast_json *, expected_message1, NULL, ast_json_unref);
137         RAII_VAR(struct ast_json *, message, NULL, ast_json_unref);
138         RAII_VAR(struct ast_json *, expected_message2, NULL, ast_json_unref);
139         char eid[20];
140         int res;
141
142         switch (cmd) {
143         case TEST_INIT:
144                 info->name = __func__;
145                 info->category = test_category;
146                 info->summary = "Test stasis app invocation.";
147                 info->description = "Test stasis app invocation.";
148                 return AST_TEST_NOT_RUN;
149         case TEST_EXECUTE:
150                 break;
151         }
152
153         app_name = "test-handler";
154
155         app_data1 = app_data_create();
156         app_data2 = app_data_create();
157
158         stasis_app_register(app_name, test_handler, app_data1);
159         stasis_app_register(app_name, test_handler, app_data2);
160         expected_message1 = ast_json_pack("[{s: s, s: s, s: s}]",
161                 "type", "ApplicationReplaced",
162                 "application", app_name,
163                 "asterisk_id", ast_eid_to_str(eid, sizeof(eid), &ast_eid_default));
164         message = ast_json_pack("{ s: o }", "test-message", ast_json_null());
165         expected_message2 = ast_json_pack("[o]", ast_json_ref(message));
166
167         res = stasis_app_send(app_name, message);
168         ast_test_validate(test, 0 == res);
169         ast_test_validate(test, 1 == app_data1->invocations);
170         ast_test_validate(test, ast_json_equal(expected_message1, app_data1->messages));
171         ast_test_validate(test, 1 == app_data2->invocations);
172         ast_test_validate(test, ast_json_equal(expected_message2, app_data2->messages));
173
174         return AST_TEST_PASS;
175 }
176
177 static int unload_module(void)
178 {
179         AST_TEST_UNREGISTER(app_invoke_dne);
180         AST_TEST_UNREGISTER(app_invoke_one);
181         AST_TEST_UNREGISTER(app_replaced);
182         stasis_app_unref();
183         return 0;
184 }
185
186 static int load_module(void)
187 {
188         stasis_app_ref();
189         AST_TEST_REGISTER(app_replaced);
190         AST_TEST_REGISTER(app_invoke_one);
191         AST_TEST_REGISTER(app_invoke_dne);
192         return AST_MODULE_LOAD_SUCCESS;
193 }
194
195 AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_DEFAULT, "Stasis Core testing",
196         .load = load_module,
197         .unload = unload_module,
198         .requires = "res_stasis",
199 );