blob: 0361e61782a46b083af1c7a79493ccad45a1fd7a [file] [log] [blame]
Alexandre Lision67916dd2014-01-24 13:33:04 -05001/* $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
49pjsip_endpoint *endpt;
50pj_caching_pool caching_pool;
51int log_level = 3;
52int param_log_decor = PJ_LOG_HAS_NEWLINE | PJ_LOG_HAS_TIME |
53 PJ_LOG_HAS_MICRO_SEC | PJ_LOG_HAS_INDENT;
54
55static pj_oshandle_t fd_report;
56const char *system_name = "Unknown";
57static char buf[1024];
58
59void app_perror(const char *msg, pj_status_t rc)
60{
61 char errbuf[256];
62
63 PJ_CHECK_STACK();
64
65 pj_strerror(rc, errbuf, sizeof(errbuf));
66 PJ_LOG(3,(THIS_FILE, "%s: [pj_status_t=%d] %s", msg, rc, errbuf));
67
68}
69
70void flush_events(unsigned duration)
71{
72 pj_time_val stop_time;
73
74 pj_gettimeofday(&stop_time);
75 stop_time.msec += duration;
76 pj_time_val_normalize(&stop_time);
77
78 /* Process all events for the specified duration. */
79 for (;;) {
80 pj_time_val timeout = {0, 1}, now;
81
82 pjsip_endpt_handle_events(endpt, &timeout);
83
84 pj_gettimeofday(&now);
85 if (PJ_TIME_VAL_GTE(now, stop_time))
86 break;
87 }
88}
89
90pj_status_t register_static_modules(pj_size_t *count, pjsip_module **modules)
91{
92 PJ_UNUSED_ARG(modules);
93
94 *count = 0;
95 return PJ_SUCCESS;
96}
97
98static pj_status_t init_report(void)
99{
100 char tmp[80];
101 pj_time_val timestamp;
102 pj_parsed_time date_time;
103 pj_ssize_t len;
104 pj_status_t status;
105
106 pj_ansi_sprintf(tmp, "pjsip-static-bench-%s-%s.htm", PJ_OS_NAME, PJ_CC_NAME);
107
108 status = pj_file_open(NULL, tmp, PJ_O_WRONLY, &fd_report);
109 if (status != PJ_SUCCESS)
110 return status;
111
112 /* Title */
113 len = pj_ansi_sprintf(buf, "<HTML>\n"
114 " <HEAD>\n"
115 " <TITLE>PJSIP %s (%s) - Static Benchmark</TITLE>\n"
116 " </HEAD>\n"
117 "<BODY>\n"
118 "\n",
119 PJ_VERSION,
120 (PJ_DEBUG ? "Debug" : "Release"));
121 pj_file_write(fd_report, buf, &len);
122
123
124 /* Title */
125 len = pj_ansi_sprintf(buf, "<H1>PJSIP %s (%s) - Static Benchmark</H1>\n",
126 PJ_VERSION,
127 (PJ_DEBUG ? "Debug" : "Release"));
128 pj_file_write(fd_report, buf, &len);
129
130 len = pj_ansi_sprintf(buf, "<P>Below is the benchmark result generated "
131 "by <b>test-pjsip</b> program. The program "
132 "is single-threaded only.</P>\n");
133 pj_file_write(fd_report, buf, &len);
134
135
136 /* Write table heading */
137 len = pj_ansi_sprintf(buf, "<TABLE border=\"1\" cellpadding=\"4\">\n"
138 " <TR><TD bgColor=\"aqua\" align=\"center\">Variable</TD>\n"
139 " <TD bgColor=\"aqua\" align=\"center\">Value</TD>\n"
140 " <TD bgColor=\"aqua\" align=\"center\">Description</TD>\n"
141 " </TR>\n");
142 pj_file_write(fd_report, buf, &len);
143
144
145 /* Write version */
146 report_sval("version", PJ_VERSION, "", "PJLIB/PJSIP version");
147
148
149 /* Debug or release */
150 report_sval("build-type", (PJ_DEBUG ? "Debug" : "Release"), "", "Build type");
151
152
153 /* Write timestamp */
154 pj_gettimeofday(&timestamp);
155 report_ival("timestamp", timestamp.sec, "", "System timestamp of the test");
156
157
158 /* Write time of day */
159 pj_time_decode(&timestamp, &date_time);
160 len = pj_ansi_sprintf(tmp, "%04d-%02d-%02d %02d:%02d:%02d",
161 date_time.year, date_time.mon+1, date_time.day,
162 date_time.hour, date_time.min, date_time.sec);
163 report_sval("date-time", tmp, "", "Date/time of the test");
164
165
166 /* Write System */
167 report_sval("system", system_name, "", "System description");
168
169
170 /* Write OS type */
171 report_sval("os-family", PJ_OS_NAME, "", "Operating system family");
172
173
174 /* Write CC name */
175 len = pj_ansi_sprintf(tmp, "%s-%d.%d.%d", PJ_CC_NAME,
176 PJ_CC_VER_1, PJ_CC_VER_2, PJ_CC_VER_2);
177 report_sval("cc-name", tmp, "", "Compiler name and version");
178
179
180 return PJ_SUCCESS;
181}
182
183void report_sval(const char *name, const char* value, const char *valname,
184 const char *desc)
185{
186 pj_ssize_t len;
187
188 len = pj_ansi_sprintf(buf, " <TR><TD><TT>%s</TT></TD>\n"
189 " <TD align=\"right\"><B>%s %s</B></TD>\n"
190 " <TD>%s</TD>\n"
191 " </TR>\n",
192 name, value, valname, desc);
193 pj_file_write(fd_report, buf, &len);
194}
195
196
197void report_ival(const char *name, int value, const char *valname,
198 const char *desc)
199{
200 pj_ssize_t len;
201
202 len = pj_ansi_sprintf(buf, " <TR><TD><TT>%s</TT></TD>\n"
203 " <TD align=\"right\"><B>%d %s</B></TD>\n"
204 " <TD>%s</TD>\n"
205 " </TR>\n",
206 name, value, valname, desc);
207 pj_file_write(fd_report, buf, &len);
208
209}
210
211static void close_report(void)
212{
213 pj_ssize_t len;
214
215 if (fd_report) {
216 len = pj_ansi_sprintf(buf, "</TABLE>\n</BODY>\n</HTML>\n");
217 pj_file_write(fd_report, buf, &len);
218
219 pj_file_close(fd_report);
220 }
221}
222
223
224int test_main(void)
225{
226 pj_status_t rc;
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 * Better be last because it recreates the endpt
374 */
375#if INCLUDE_TSX_DESTROY_TEST
376 DO_TEST(tsx_destroy_test());
377#endif
378
379on_return:
380 flush_events(500);
381
382 /* Dumping memory pool usage */
383 PJ_LOG(3,(THIS_FILE, "Peak memory size=%u MB",
384 caching_pool.peak_used_size / 1000000));
385
386 pjsip_endpt_destroy(endpt);
387 pj_caching_pool_destroy(&caching_pool);
388
389 PJ_LOG(3,(THIS_FILE, ""));
390
391 pj_thread_get_stack_info(pj_thread_this(), &filename, &line);
392 PJ_LOG(3,(THIS_FILE, "Stack max usage: %u, deepest: %s:%u",
393 pj_thread_get_stack_max_usage(pj_thread_this()),
394 filename, line));
395 if (rc == 0)
396 PJ_LOG(3,(THIS_FILE, "Looks like everything is okay!.."));
397 else
398 PJ_LOG(3,(THIS_FILE, "Test completed with error(s)"));
399
400 report_ival("test-status", rc, "", "Overall test status/result (0==success)");
401 close_report();
402 return rc;
403}
404