Add support for ICE/STUN/TURN in res_rtp_asterisk and chan_sip.
[asterisk/asterisk.git] / res / pjproject / pjsip / src / test / test.c
1 /* $Id$ */
2 /* 
3  * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
4  * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA 
19  */
20
21
22 #include "test.h"
23 #include <pjlib.h>
24 #include <pjlib-util.h>
25 #include <pjsip.h>
26
27 #define THIS_FILE   "test.c"
28
29 #define DO_TEST(test)   do { \
30                             PJ_LOG(3, (THIS_FILE, "Running %s...", #test));  \
31                             rc = test; \
32                             PJ_LOG(3, (THIS_FILE,  \
33                                        "%s(%d)",  \
34                                        (rc ? "..ERROR" : "..success"), rc)); \
35                             if (rc!=0) goto on_return; \
36                         } while (0)
37
38 #define DO_TSX_TEST(test, param) \
39                         do { \
40                             PJ_LOG(3, (THIS_FILE, "Running %s(%s)...", #test, (param)->tp_type));  \
41                             rc = test(param); \
42                             PJ_LOG(3, (THIS_FILE,  \
43                                        "%s(%d)",  \
44                                        (rc ? "..ERROR" : "..success"), rc)); \
45                             if (rc!=0) goto on_return; \
46                         } while (0)
47
48
49 pjsip_endpoint *endpt;
50 int log_level = 3;
51 int param_log_decor = PJ_LOG_HAS_NEWLINE | PJ_LOG_HAS_TIME | 
52                       PJ_LOG_HAS_MICRO_SEC;
53
54 static pj_oshandle_t fd_report;
55 const char *system_name = "Unknown";
56 static char buf[1024];
57
58 void app_perror(const char *msg, pj_status_t rc)
59 {
60     char errbuf[256];
61
62     PJ_CHECK_STACK();
63
64     pj_strerror(rc, errbuf, sizeof(errbuf));
65     PJ_LOG(3,(THIS_FILE, "%s: [pj_status_t=%d] %s", msg, rc, errbuf));
66
67 }
68
69 void flush_events(unsigned duration)
70 {
71     pj_time_val stop_time;
72
73     pj_gettimeofday(&stop_time);
74     stop_time.msec += duration;
75     pj_time_val_normalize(&stop_time);
76
77     /* Process all events for the specified duration. */
78     for (;;) {
79         pj_time_val timeout = {0, 1}, now;
80
81         pjsip_endpt_handle_events(endpt, &timeout);
82
83         pj_gettimeofday(&now);
84         if (PJ_TIME_VAL_GTE(now, stop_time))
85             break;
86     }
87 }
88
89 pj_status_t register_static_modules(pj_size_t *count, pjsip_module **modules)
90 {
91     PJ_UNUSED_ARG(modules);
92
93     *count = 0;
94     return PJ_SUCCESS;
95 }
96
97 static pj_status_t init_report(void)
98 {
99     char tmp[80];
100     pj_time_val timestamp;
101     pj_parsed_time date_time;
102     pj_ssize_t len;
103     pj_status_t status;
104     
105     pj_ansi_sprintf(tmp, "pjsip-static-bench-%s-%s.htm", PJ_OS_NAME, PJ_CC_NAME);
106
107     status = pj_file_open(NULL, tmp, PJ_O_WRONLY, &fd_report);
108     if (status != PJ_SUCCESS)
109         return status;
110
111     /* Title */
112     len = pj_ansi_sprintf(buf, "<HTML>\n"
113                                " <HEAD>\n"
114                                "  <TITLE>PJSIP %s (%s) - Static Benchmark</TITLE>\n"
115                                " </HEAD>\n"
116                                "<BODY>\n"
117                                "\n", 
118                                PJ_VERSION,
119                                (PJ_DEBUG ? "Debug" : "Release"));
120     pj_file_write(fd_report, buf, &len);
121
122
123     /* Title */
124     len = pj_ansi_sprintf(buf, "<H1>PJSIP %s (%s) - Static Benchmark</H1>\n", 
125                                PJ_VERSION,
126                                (PJ_DEBUG ? "Debug" : "Release"));
127     pj_file_write(fd_report, buf, &len);
128
129     len = pj_ansi_sprintf(buf, "<P>Below is the benchmark result generated "
130                                "by <b>test-pjsip</b> program. The program "
131                                "is single-threaded only.</P>\n");
132     pj_file_write(fd_report, buf, &len);
133
134
135     /* Write table heading */
136     len = pj_ansi_sprintf(buf, "<TABLE border=\"1\" cellpadding=\"4\">\n"
137                                "  <TR><TD bgColor=\"aqua\" align=\"center\">Variable</TD>\n"
138                                "      <TD bgColor=\"aqua\" align=\"center\">Value</TD>\n"
139                                "      <TD bgColor=\"aqua\" align=\"center\">Description</TD>\n"
140                                "  </TR>\n");
141     pj_file_write(fd_report, buf, &len);
142
143
144     /* Write version */
145     report_sval("version", PJ_VERSION, "", "PJLIB/PJSIP version");
146
147
148     /* Debug or release */
149     report_sval("build-type", (PJ_DEBUG ? "Debug" : "Release"), "", "Build type");
150
151
152     /* Write timestamp */
153     pj_gettimeofday(&timestamp);
154     report_ival("timestamp", timestamp.sec, "", "System timestamp of the test");
155
156
157     /* Write time of day */
158     pj_time_decode(&timestamp, &date_time);
159     len = pj_ansi_sprintf(tmp, "%04d-%02d-%02d %02d:%02d:%02d",
160                                date_time.year, date_time.mon+1, date_time.day,
161                                date_time.hour, date_time.min, date_time.sec);
162     report_sval("date-time", tmp, "", "Date/time of the test");
163
164
165     /* Write System */
166     report_sval("system", system_name, "", "System description");
167
168
169     /* Write OS type */
170     report_sval("os-family", PJ_OS_NAME, "", "Operating system family");
171
172
173     /* Write CC name */
174     len = pj_ansi_sprintf(tmp, "%s-%d.%d.%d", PJ_CC_NAME, 
175                           PJ_CC_VER_1, PJ_CC_VER_2, PJ_CC_VER_2);
176     report_sval("cc-name", tmp, "", "Compiler name and version");
177
178
179     return PJ_SUCCESS;
180 }
181
182 void report_sval(const char *name, const char* value, const char *valname, 
183                  const char *desc)
184 {
185     pj_ssize_t len;
186
187     len = pj_ansi_sprintf(buf, "  <TR><TD><TT>%s</TT></TD>\n"
188                                "      <TD align=\"right\"><B>%s %s</B></TD>\n"
189                                "      <TD>%s</TD>\n"
190                                "  </TR>\n",
191                                name, value, valname, desc);
192     pj_file_write(fd_report, buf, &len);
193 }
194
195
196 void report_ival(const char *name, int value, const char *valname, 
197                  const char *desc)
198 {
199     pj_ssize_t len;
200
201     len = pj_ansi_sprintf(buf, "  <TR><TD><TT>%s</TT></TD>\n"
202                                "      <TD align=\"right\"><B>%d %s</B></TD>\n"
203                                "      <TD>%s</TD>\n"
204                                "  </TR>\n",
205                                name, value, valname, desc);
206     pj_file_write(fd_report, buf, &len);
207
208 }
209
210 static void close_report(void)
211 {
212     pj_ssize_t len;
213
214     if (fd_report) {
215         len = pj_ansi_sprintf(buf, "</TABLE>\n</BODY>\n</HTML>\n");
216         pj_file_write(fd_report, buf, &len);
217
218         pj_file_close(fd_report);
219     }
220 }
221
222
223 int test_main(void)
224 {
225     pj_status_t rc;
226     pj_caching_pool caching_pool;
227     const char *filename;
228     unsigned tsx_test_cnt=0;
229     struct tsx_test_param tsx_test[10];
230     pj_status_t status;
231 #if INCLUDE_TSX_TEST
232     unsigned i;
233     pjsip_transport *tp;
234 #if PJ_HAS_TCP
235     pjsip_tpfactory *tpfactory;
236 #endif  /* PJ_HAS_TCP */
237 #endif  /* INCLUDE_TSX_TEST */
238     int line;
239
240     pj_log_set_level(log_level);
241     pj_log_set_decor(param_log_decor);
242
243     if ((rc=pj_init()) != PJ_SUCCESS) {
244         app_perror("pj_init", rc);
245         return rc;
246     }
247
248     if ((rc=pjlib_util_init()) != PJ_SUCCESS) {
249         app_perror("pj_init", rc);
250         return rc;
251     }
252
253     status = init_report();
254     if (status != PJ_SUCCESS)
255         return status;
256
257     pj_dump_config();
258
259     pj_caching_pool_init( &caching_pool, &pj_pool_factory_default_policy, 
260                           PJSIP_TEST_MEM_SIZE );
261
262     rc = pjsip_endpt_create(&caching_pool.factory, "endpt", &endpt);
263     if (rc != PJ_SUCCESS) {
264         app_perror("pjsip_endpt_create", rc);
265         pj_caching_pool_destroy(&caching_pool);
266         return rc;
267     }
268
269     PJ_LOG(3,(THIS_FILE,""));
270
271     /* Init logger module. */
272     init_msg_logger();
273     msg_logger_set_enabled(1);
274
275     /* Start transaction layer module. */
276     rc = pjsip_tsx_layer_init_module(endpt);
277     if (rc != PJ_SUCCESS) {
278         app_perror("   Error initializing transaction module", rc);
279         goto on_return;
280     }
281
282     /* Create loop transport. */
283     rc = pjsip_loop_start(endpt, NULL);
284     if (rc != PJ_SUCCESS) {
285         app_perror("   error: unable to create datagram loop transport", 
286                    rc);
287         goto on_return;
288     }
289     tsx_test[tsx_test_cnt].port = 5060;
290     tsx_test[tsx_test_cnt].tp_type = "loop-dgram";
291     tsx_test[tsx_test_cnt].type = PJSIP_TRANSPORT_LOOP_DGRAM;
292     ++tsx_test_cnt;
293
294
295 #if INCLUDE_URI_TEST
296     DO_TEST(uri_test());
297 #endif
298
299 #if INCLUDE_MSG_TEST
300     DO_TEST(msg_test());
301     DO_TEST(msg_err_test());
302 #endif
303
304 #if INCLUDE_MULTIPART_TEST
305     DO_TEST(multipart_test());
306 #endif
307
308 #if INCLUDE_TXDATA_TEST
309     DO_TEST(txdata_test());
310 #endif
311
312 #if INCLUDE_TSX_BENCH
313     DO_TEST(tsx_bench());
314 #endif
315
316 #if INCLUDE_UDP_TEST
317     DO_TEST(transport_udp_test());
318 #endif
319
320 #if INCLUDE_LOOP_TEST
321     DO_TEST(transport_loop_test());
322 #endif
323
324 #if INCLUDE_TCP_TEST
325     DO_TEST(transport_tcp_test());
326 #endif
327
328 #if INCLUDE_RESOLVE_TEST
329     DO_TEST(resolve_test());
330 #endif
331
332
333 #if INCLUDE_TSX_TEST
334     status = pjsip_udp_transport_start(endpt, NULL, NULL, 1,  &tp);
335     if (status == PJ_SUCCESS) {
336         tsx_test[tsx_test_cnt].port = tp->local_name.port;
337         tsx_test[tsx_test_cnt].tp_type = "udp";
338         tsx_test[tsx_test_cnt].type = PJSIP_TRANSPORT_UDP;
339         ++tsx_test_cnt;
340     }
341
342 #if PJ_HAS_TCP
343     status = pjsip_tcp_transport_start(endpt, NULL, 1, &tpfactory);
344     if (status == PJ_SUCCESS) {
345         tsx_test[tsx_test_cnt].port = tpfactory->addr_name.port;
346         tsx_test[tsx_test_cnt].tp_type = "tcp";
347         tsx_test[tsx_test_cnt].type = PJSIP_TRANSPORT_TCP;
348         ++tsx_test_cnt;
349     } else {
350         app_perror("Unable to create TCP", status);
351         rc = -4;
352         goto on_return;
353     }
354 #endif
355
356
357     for (i=0; i<tsx_test_cnt; ++i) {
358         DO_TSX_TEST(tsx_basic_test, &tsx_test[i]);
359         DO_TSX_TEST(tsx_uac_test, &tsx_test[i]);
360         DO_TSX_TEST(tsx_uas_test, &tsx_test[i]);
361     }
362 #endif
363
364 #if INCLUDE_INV_OA_TEST
365     DO_TEST(inv_offer_answer_test());
366 #endif
367
368 #if INCLUDE_REGC_TEST
369     DO_TEST(regc_test());
370 #endif
371
372
373 on_return:
374     flush_events(500);
375
376     /* Dumping memory pool usage */
377     PJ_LOG(3,(THIS_FILE, "Peak memory size=%u MB",
378                          caching_pool.peak_used_size / 1000000));
379
380     pjsip_endpt_destroy(endpt);
381     pj_caching_pool_destroy(&caching_pool);
382
383     PJ_LOG(3,(THIS_FILE, ""));
384  
385     pj_thread_get_stack_info(pj_thread_this(), &filename, &line);
386     PJ_LOG(3,(THIS_FILE, "Stack max usage: %u, deepest: %s:%u", 
387                       pj_thread_get_stack_max_usage(pj_thread_this()),
388                       filename, line));
389     if (rc == 0)
390         PJ_LOG(3,(THIS_FILE, "Looks like everything is okay!.."));
391     else
392         PJ_LOG(3,(THIS_FILE, "Test completed with error(s)"));
393
394     report_ival("test-status", rc, "", "Overall test status/result (0==success)");
395     close_report();
396     return rc;
397 }
398