Add additional namespaces for Google Talk which are used for the gmail client.
[asterisk/asterisk.git] / tests / test_sched.c
1 /*
2  * Asterisk -- An open source telephony toolkit.
3  *
4  * Copyright (C) 2009, Digium, Inc.
5  *
6  * Russell Bryant <russell@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 ast_sched performance test module
22  *
23  * \author Russell Bryant <russell@digium.com>
24  */
25
26 /*** MODULEINFO
27         <depend>TEST_FRAMEWORK</depend>
28         <support_level>core</support_level>
29  ***/
30
31 #include "asterisk.h"
32
33 #include <inttypes.h>
34
35 ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
36
37 #include "asterisk/module.h"
38 #include "asterisk/utils.h"
39 #include "asterisk/sched.h"
40 #include "asterisk/test.h"
41 #include "asterisk/cli.h"
42
43 static int sched_cb(const void *data)
44 {
45         return 0;
46 }
47
48 AST_TEST_DEFINE(sched_test_order)
49 {
50         struct ast_sched_context *con;
51         enum ast_test_result_state res = AST_TEST_FAIL;
52         int id1, id2, id3, wait;
53
54         switch (cmd) {
55         case TEST_INIT:
56                 info->name = "sched_test_order";
57                 info->category = "/main/sched/";
58                 info->summary = "Test ordering of events in the scheduler API";
59                 info->description =
60                         "This test ensures that events are properly ordered by the "
61                         "time they are scheduled to execute in the scheduler API.";
62                 return AST_TEST_NOT_RUN;
63         case TEST_EXECUTE:
64                 break;
65         }
66
67         if (!(con = ast_sched_context_create())) {
68                 ast_test_status_update(test,
69                                 "Test failed - could not create scheduler context\n");
70                 return AST_TEST_FAIL;
71         }
72
73         /* Add 3 scheduler entries, and then remove them, ensuring that the result
74          * of ast_sched_wait() looks appropriate at each step along the way. */
75
76         if ((wait = ast_sched_wait(con)) != -1) {
77                 ast_test_status_update(test,
78                                 "ast_sched_wait() should have returned -1, returned '%d'\n",
79                                 wait);
80                 goto return_cleanup;
81         }
82
83         if ((id1 = ast_sched_add(con, 100000, sched_cb, NULL)) == -1) {
84                 ast_test_status_update(test, "Failed to add scheduler entry\n");
85                 goto return_cleanup;
86         }
87
88         if ((wait = ast_sched_wait(con)) > 100000) {
89                 ast_test_status_update(test,
90                                 "ast_sched_wait() should have returned <= 100000, returned '%d'\n",
91                                 wait);
92                 goto return_cleanup;
93         }
94
95         if ((id2 = ast_sched_add(con, 10000, sched_cb, NULL)) == -1) {
96                 ast_test_status_update(test, "Failed to add scheduler entry\n");
97                 goto return_cleanup;
98         }
99
100         if ((wait = ast_sched_wait(con)) > 10000) {
101                 ast_test_status_update(test,
102                                 "ast_sched_wait() should have returned <= 10000, returned '%d'\n",
103                                 wait);
104                 goto return_cleanup;
105         }
106
107         if ((id3 = ast_sched_add(con, 1000, sched_cb, NULL)) == -1) {
108                 ast_test_status_update(test, "Failed to add scheduler entry\n");
109                 goto return_cleanup;
110         }
111
112         if ((wait = ast_sched_wait(con)) > 1000) {
113                 ast_test_status_update(test,
114                                 "ast_sched_wait() should have returned <= 1000, returned '%d'\n",
115                                 wait);
116                 goto return_cleanup;
117         }
118
119         if (ast_sched_del(con, id3) == -1) {
120                 ast_test_status_update(test, "Failed to remove scheduler entry\n");
121                 goto return_cleanup;
122         }
123
124         if ((wait = ast_sched_wait(con)) <= 1000) {
125                 ast_test_status_update(test,
126                                 "ast_sched_wait() should have returned > 1000, returned '%d'\n",
127                                 wait);
128                 goto return_cleanup;
129         }
130
131         if (ast_sched_del(con, id2) == -1) {
132                 ast_test_status_update(test, "Failed to remove scheduler entry\n");
133                 goto return_cleanup;
134         }
135
136         if ((wait = ast_sched_wait(con)) <= 10000) {
137                 ast_test_status_update(test,
138                                 "ast_sched_wait() should have returned > 10000, returned '%d'\n",
139                                 wait);
140                 goto return_cleanup;
141         }
142
143         if (ast_sched_del(con, id1) == -1) {
144                 ast_test_status_update(test, "Failed to remove scheduler entry\n");
145                 goto return_cleanup;
146         }
147
148         if ((wait = ast_sched_wait(con)) != -1) {
149                 ast_test_status_update(test,
150                                 "ast_sched_wait() should have returned -1, returned '%d'\n",
151                                 wait);
152                 goto return_cleanup;
153         }
154
155         res = AST_TEST_PASS;
156
157 return_cleanup:
158         ast_sched_context_destroy(con);
159
160         return res;
161 }
162
163 static char *handle_cli_sched_bench(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
164 {
165         struct ast_sched_context *con;
166         struct timeval start;
167         unsigned int num, i;
168         int *sched_ids = NULL;
169
170         switch (cmd) {
171         case CLI_INIT:
172                 e->command = "sched benchmark";
173                 e->usage = ""
174                         "Usage: sched benchmark <num>\n"
175                         "";
176                 return NULL;
177         case CLI_GENERATE:
178                 return NULL;
179         }
180
181         if (a->argc != e->args + 1) {
182                 return CLI_SHOWUSAGE;
183         }
184
185         if (sscanf(a->argv[e->args], "%u", &num) != 1) {
186                 return CLI_SHOWUSAGE;
187         }
188
189         if (!(con = ast_sched_context_create())) {
190                 ast_cli(a->fd, "Test failed - could not create scheduler context\n");
191                 return CLI_FAILURE;
192         }
193
194         if (!(sched_ids = ast_malloc(sizeof(*sched_ids) * num))) {
195                 ast_cli(a->fd, "Test failed - memory allocation failure\n");
196                 goto return_cleanup;
197         }
198
199         ast_cli(a->fd, "Testing ast_sched_add() performance - timing how long it takes "
200                         "to add %u entries at random time intervals from 0 to 60 seconds\n", num);
201
202         start = ast_tvnow();
203
204         for (i = 0; i < num; i++) {
205                 int when = abs(ast_random()) % 60000;
206                 if ((sched_ids[i] = ast_sched_add(con, when, sched_cb, NULL)) == -1) {
207                         ast_cli(a->fd, "Test failed - sched_add returned -1\n");
208                         goto return_cleanup;
209                 }
210         }
211
212         ast_cli(a->fd, "Test complete - %" PRIi64 " us\n", ast_tvdiff_us(ast_tvnow(), start));
213
214         ast_cli(a->fd, "Testing ast_sched_del() performance - timing how long it takes "
215                         "to delete %u entries with random time intervals from 0 to 60 seconds\n", num);
216
217         start = ast_tvnow();
218
219         for (i = 0; i < num; i++) {
220                 if (ast_sched_del(con, sched_ids[i]) == -1) {
221                         ast_cli(a->fd, "Test failed - sched_del returned -1\n");
222                         goto return_cleanup;
223                 }
224         }
225
226         ast_cli(a->fd, "Test complete - %" PRIi64 " us\n", ast_tvdiff_us(ast_tvnow(), start));
227
228 return_cleanup:
229         ast_sched_context_destroy(con);
230         if (sched_ids) {
231                 ast_free(sched_ids);
232         }
233
234         return CLI_SUCCESS;
235 }
236
237 static struct ast_cli_entry cli_sched[] = {
238         AST_CLI_DEFINE(handle_cli_sched_bench, "Benchmark ast_sched add/del performance"),
239 };
240
241 static int unload_module(void)
242 {
243         AST_TEST_UNREGISTER(sched_test_order);
244         ast_cli_unregister_multiple(cli_sched, ARRAY_LEN(cli_sched));
245         return 0;
246 }
247
248 static int load_module(void)
249 {
250         AST_TEST_REGISTER(sched_test_order);
251         ast_cli_register_multiple(cli_sched, ARRAY_LEN(cli_sched));
252         return AST_MODULE_LOAD_SUCCESS;
253 }
254
255 AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "ast_sched performance test module");