blob: 09ee1244d0b755ad7612393eff8fe88da4066d35 [file] [log] [blame]
Benny Prijono5dcb38d2005-11-21 01:55:47 +00001/* $Id$ */
2/*
Benny Prijonoa771a512007-02-19 01:13:53 +00003 * Copyright (C) 2003-2007 Benny Prijono <benny@prijono.org>
Benny Prijono5dcb38d2005-11-21 01:55:47 +00004 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 */
19
20
21#include "test.h"
22#include <pjlib.h>
Benny Prijonofa9e5b12006-10-08 12:39:34 +000023#include <pjlib-util.h>
Benny Prijono40f2f642006-01-30 18:40:05 +000024#include <pjsip.h>
Benny Prijono5dcb38d2005-11-21 01:55:47 +000025
Benny Prijono85598d92006-01-07 18:44:25 +000026#define THIS_FILE "test.c"
27
Benny Prijono5dcb38d2005-11-21 01:55:47 +000028#define DO_TEST(test) do { \
Benny Prijono85598d92006-01-07 18:44:25 +000029 PJ_LOG(3, (THIS_FILE, "Running %s...", #test)); \
Benny Prijono5dcb38d2005-11-21 01:55:47 +000030 rc = test; \
Benny Prijono85598d92006-01-07 18:44:25 +000031 PJ_LOG(3, (THIS_FILE, \
Benny Prijono5dcb38d2005-11-21 01:55:47 +000032 "%s(%d)", \
33 (rc ? "..ERROR" : "..success"), rc)); \
34 if (rc!=0) goto on_return; \
35 } while (0)
36
Benny Prijonoe93e2872006-06-28 16:46:49 +000037#define DO_TSX_TEST(test, param) \
38 do { \
39 PJ_LOG(3, (THIS_FILE, "Running %s(%s)...", #test, (param)->tp_type)); \
40 rc = test(param); \
41 PJ_LOG(3, (THIS_FILE, \
42 "%s(%d)", \
43 (rc ? "..ERROR" : "..success"), rc)); \
44 if (rc!=0) goto on_return; \
45 } while (0)
Benny Prijono5dcb38d2005-11-21 01:55:47 +000046
47
48pjsip_endpoint *endpt;
Benny Prijono733c67a2006-06-23 01:03:52 +000049int log_level = 3;
Benny Prijono5dcb38d2005-11-21 01:55:47 +000050
Benny Prijonoe93e2872006-06-28 16:46:49 +000051static pj_oshandle_t fd_report;
52const char *system_name = "Unknown";
53static char buf[1024];
54
Benny Prijono5dcb38d2005-11-21 01:55:47 +000055void app_perror(const char *msg, pj_status_t rc)
56{
57 char errbuf[256];
58
59 PJ_CHECK_STACK();
60
Benny Prijono733c67a2006-06-23 01:03:52 +000061 pj_strerror(rc, errbuf, sizeof(errbuf));
Benny Prijono85598d92006-01-07 18:44:25 +000062 PJ_LOG(3,(THIS_FILE, "%s: [pj_status_t=%d] %s", msg, rc, errbuf));
Benny Prijono5dcb38d2005-11-21 01:55:47 +000063
64}
65
Benny Prijono85598d92006-01-07 18:44:25 +000066void flush_events(unsigned duration)
67{
68 pj_time_val stop_time;
69
70 pj_gettimeofday(&stop_time);
71 stop_time.msec += duration;
72 pj_time_val_normalize(&stop_time);
73
74 /* Process all events for the specified duration. */
75 for (;;) {
76 pj_time_val timeout = {0, 1}, now;
77
78 pjsip_endpt_handle_events(endpt, &timeout);
79
80 pj_gettimeofday(&now);
81 if (PJ_TIME_VAL_GTE(now, stop_time))
82 break;
83 }
84}
85
Benny Prijono5dcb38d2005-11-21 01:55:47 +000086pj_status_t register_static_modules(pj_size_t *count, pjsip_module **modules)
87{
88 *count = 0;
89 return PJ_SUCCESS;
90}
91
Benny Prijonoe93e2872006-06-28 16:46:49 +000092static pj_status_t init_report(void)
93{
94 char tmp[80];
95 pj_time_val timestamp;
96 pj_parsed_time date_time;
97 pj_ssize_t len;
98 pj_status_t status;
99
100 pj_ansi_sprintf(tmp, "pjsip-static-bench-%s-%s.htm", PJ_OS_NAME, PJ_CC_NAME);
101
102 status = pj_file_open(NULL, tmp, PJ_O_WRONLY, &fd_report);
103 if (status != PJ_SUCCESS)
104 return status;
105
106 /* Title */
107 len = pj_ansi_sprintf(buf, "<HTML>\n"
108 " <HEAD>\n"
109 " <TITLE>PJSIP %s (%s) - Static Benchmark</TITLE>\n"
110 " </HEAD>\n"
111 "<BODY>\n"
112 "\n",
113 PJ_VERSION,
114 (PJ_DEBUG ? "Debug" : "Release"));
115 pj_file_write(fd_report, buf, &len);
116
117
118 /* Title */
119 len = pj_ansi_sprintf(buf, "<H1>PJSIP %s (%s) - Static Benchmark</H1>\n",
120 PJ_VERSION,
121 (PJ_DEBUG ? "Debug" : "Release"));
122 pj_file_write(fd_report, buf, &len);
123
124 len = pj_ansi_sprintf(buf, "<P>Below is the benchmark result generated "
125 "by <b>test-pjsip</b> program. The program "
126 "is single-threaded only.</P>\n");
127 pj_file_write(fd_report, buf, &len);
128
129
130 /* Write table heading */
131 len = pj_ansi_sprintf(buf, "<TABLE border=\"1\" cellpadding=\"4\">\n"
132 " <TR><TD bgColor=\"aqua\" align=\"center\">Variable</TD>\n"
133 " <TD bgColor=\"aqua\" align=\"center\">Value</TD>\n"
134 " <TD bgColor=\"aqua\" align=\"center\">Description</TD>\n"
135 " </TR>\n");
136 pj_file_write(fd_report, buf, &len);
137
138
139 /* Write version */
140 report_sval("version", PJ_VERSION, "", "PJLIB/PJSIP version");
141
142
143 /* Debug or release */
144 report_sval("build-type", (PJ_DEBUG ? "Debug" : "Release"), "", "Build type");
145
146
147 /* Write timestamp */
148 pj_gettimeofday(&timestamp);
149 report_ival("timestamp", timestamp.sec, "", "System timestamp of the test");
150
151
152 /* Write time of day */
153 pj_time_decode(&timestamp, &date_time);
154 len = pj_ansi_sprintf(tmp, "%04d-%02d-%02d %02d:%02d:%02d",
155 date_time.year, date_time.mon+1, date_time.day,
156 date_time.hour, date_time.min, date_time.sec);
157 report_sval("date-time", tmp, "", "Date/time of the test");
158
159
160 /* Write System */
161 report_sval("system", system_name, "", "System description");
162
163
164 /* Write OS type */
165 report_sval("os-family", PJ_OS_NAME, "", "Operating system family");
166
167
168 /* Write CC name */
169 len = pj_ansi_sprintf(tmp, "%s-%d.%d.%d", PJ_CC_NAME,
170 PJ_CC_VER_1, PJ_CC_VER_2, PJ_CC_VER_2);
171 report_sval("cc-name", tmp, "", "Compiler name and version");
172
173
174 return PJ_SUCCESS;
175}
176
177void report_sval(const char *name, const char* value, const char *valname,
178 const char *desc)
179{
180 pj_ssize_t len;
181
182 len = pj_ansi_sprintf(buf, " <TR><TD><TT>%s</TT></TD>\n"
183 " <TD align=\"right\"><B>%s %s</B></TD>\n"
184 " <TD>%s</TD>\n"
185 " </TR>\n",
186 name, value, valname, desc);
187 pj_file_write(fd_report, buf, &len);
188}
189
190
191void report_ival(const char *name, int value, const char *valname,
192 const char *desc)
193{
194 pj_ssize_t len;
195
196 len = pj_ansi_sprintf(buf, " <TR><TD><TT>%s</TT></TD>\n"
197 " <TD align=\"right\"><B>%d %s</B></TD>\n"
198 " <TD>%s</TD>\n"
199 " </TR>\n",
200 name, value, valname, desc);
201 pj_file_write(fd_report, buf, &len);
202
203}
204
205static void close_report(void)
206{
207 pj_ssize_t len;
208
209 if (fd_report) {
210 len = pj_ansi_sprintf(buf, "</TABLE>\n</BODY>\n</HTML>\n");
211 pj_file_write(fd_report, buf, &len);
212
213 pj_file_close(fd_report);
214 }
215}
216
217
Benny Prijono5dcb38d2005-11-21 01:55:47 +0000218int test_main(void)
219{
220 pj_status_t rc;
221 pj_caching_pool caching_pool;
222 const char *filename;
Benny Prijonobc331ca2006-09-19 13:32:05 +0000223 unsigned tsx_test_cnt=0;
Benny Prijonoe93e2872006-06-28 16:46:49 +0000224 struct tsx_test_param tsx_test[10];
225 pj_status_t status;
Benny Prijonobc331ca2006-09-19 13:32:05 +0000226#if INCLUDE_TSX_TEST
227 unsigned i;
Benny Prijonoe93e2872006-06-28 16:46:49 +0000228 pjsip_transport *tp;
Benny Prijono3569c0d2007-04-06 10:29:20 +0000229#if PJ_HAS_TCP
Benny Prijonoe93e2872006-06-28 16:46:49 +0000230 pjsip_tpfactory *tpfactory;
Benny Prijono3569c0d2007-04-06 10:29:20 +0000231#endif /* PJ_HAS_TCP */
232#endif /* INCLUDE_TSX_TEST */
Benny Prijono5dcb38d2005-11-21 01:55:47 +0000233 int line;
234
Benny Prijono9c1d9f52006-01-07 23:01:56 +0000235 pj_log_set_level(log_level);
Benny Prijono85598d92006-01-07 18:44:25 +0000236 /*
Benny Prijono5dcb38d2005-11-21 01:55:47 +0000237 pj_log_set_decor(PJ_LOG_HAS_NEWLINE | PJ_LOG_HAS_TIME |
238 PJ_LOG_HAS_MICRO_SEC);
Benny Prijono85598d92006-01-07 18:44:25 +0000239 */
Benny Prijono5dcb38d2005-11-21 01:55:47 +0000240
241 if ((rc=pj_init()) != PJ_SUCCESS) {
242 app_perror("pj_init", rc);
243 return rc;
244 }
245
Benny Prijonofa9e5b12006-10-08 12:39:34 +0000246 if ((rc=pjlib_util_init()) != PJ_SUCCESS) {
247 app_perror("pj_init", rc);
248 return rc;
249 }
250
Benny Prijonoe93e2872006-06-28 16:46:49 +0000251 status = init_report();
252 if (status != PJ_SUCCESS)
253 return status;
254
Benny Prijono5dcb38d2005-11-21 01:55:47 +0000255 pj_dump_config();
256
Benny Prijono95c63482006-07-06 14:28:45 +0000257 pj_caching_pool_init( &caching_pool, &pj_pool_factory_default_policy,
258 PJSIP_TEST_MEM_SIZE );
Benny Prijono5dcb38d2005-11-21 01:55:47 +0000259
260 rc = pjsip_endpt_create(&caching_pool.factory, "endpt", &endpt);
261 if (rc != PJ_SUCCESS) {
262 app_perror("pjsip_endpt_create", rc);
263 pj_caching_pool_destroy(&caching_pool);
264 return rc;
265 }
266
Benny Prijono85598d92006-01-07 18:44:25 +0000267 PJ_LOG(3,(THIS_FILE,""));
268
269 /* Init logger module. */
270 init_msg_logger();
271 msg_logger_set_enabled(1);
272
273 /* Start transaction layer module. */
Benny Prijono733c67a2006-06-23 01:03:52 +0000274 rc = pjsip_tsx_layer_init_module(endpt);
Benny Prijono85598d92006-01-07 18:44:25 +0000275 if (rc != PJ_SUCCESS) {
276 app_perror(" Error initializing transaction module", rc);
277 goto on_return;
278 }
279
280 /* Create loop transport. */
281 rc = pjsip_loop_start(endpt, NULL);
282 if (rc != PJ_SUCCESS) {
283 app_perror(" error: unable to create datagram loop transport",
284 rc);
285 goto on_return;
286 }
Benny Prijonoe93e2872006-06-28 16:46:49 +0000287 tsx_test[tsx_test_cnt].port = 5060;
288 tsx_test[tsx_test_cnt].tp_type = "loop-dgram";
289 tsx_test[tsx_test_cnt].type = PJSIP_TRANSPORT_LOOP_DGRAM;
290 ++tsx_test_cnt;
291
Benny Prijono5dcb38d2005-11-21 01:55:47 +0000292
Benny Prijono02b8fd82006-06-26 15:12:55 +0000293#if INCLUDE_URI_TEST
Benny Prijono733c67a2006-06-23 01:03:52 +0000294 DO_TEST(uri_test());
Benny Prijono02b8fd82006-06-26 15:12:55 +0000295#endif
296
297#if INCLUDE_MSG_TEST
Benny Prijono733c67a2006-06-23 01:03:52 +0000298 DO_TEST(msg_test());
299 DO_TEST(msg_err_test());
Benny Prijono02b8fd82006-06-26 15:12:55 +0000300#endif
301
302#if INCLUDE_TXDATA_TEST
Benny Prijono733c67a2006-06-23 01:03:52 +0000303 DO_TEST(txdata_test());
Benny Prijono02b8fd82006-06-26 15:12:55 +0000304#endif
305
Benny Prijonoe93e2872006-06-28 16:46:49 +0000306#if INCLUDE_TSX_BENCH
307 DO_TEST(tsx_bench());
308#endif
309
Benny Prijono02b8fd82006-06-26 15:12:55 +0000310#if INCLUDE_UDP_TEST
Benny Prijono733c67a2006-06-23 01:03:52 +0000311 DO_TEST(transport_udp_test());
Benny Prijono02b8fd82006-06-26 15:12:55 +0000312#endif
313
314#if INCLUDE_LOOP_TEST
Benny Prijono733c67a2006-06-23 01:03:52 +0000315 DO_TEST(transport_loop_test());
Benny Prijono02b8fd82006-06-26 15:12:55 +0000316#endif
317
Benny Prijonoe93e2872006-06-28 16:46:49 +0000318#if INCLUDE_TCP_TEST
319 DO_TEST(transport_tcp_test());
320#endif
321
Benny Prijonofa9e5b12006-10-08 12:39:34 +0000322#if INCLUDE_RESOLVE_TEST
323 DO_TEST(resolve_test());
324#endif
325
Benny Prijonoe93e2872006-06-28 16:46:49 +0000326
Benny Prijono02b8fd82006-06-26 15:12:55 +0000327#if INCLUDE_TSX_TEST
Benny Prijonoe93e2872006-06-28 16:46:49 +0000328 status = pjsip_udp_transport_start(endpt, NULL, NULL, 1, &tp);
329 if (status == PJ_SUCCESS) {
330 tsx_test[tsx_test_cnt].port = tp->local_name.port;
331 tsx_test[tsx_test_cnt].tp_type = "udp";
332 tsx_test[tsx_test_cnt].type = PJSIP_TRANSPORT_UDP;
333 ++tsx_test_cnt;
334 }
335
Benny Prijono3569c0d2007-04-06 10:29:20 +0000336#if PJ_HAS_TCP
Benny Prijonoe93e2872006-06-28 16:46:49 +0000337 status = pjsip_tcp_transport_start(endpt, NULL, 1, &tpfactory);
338 if (status == PJ_SUCCESS) {
339 tsx_test[tsx_test_cnt].port = tpfactory->addr_name.port;
340 tsx_test[tsx_test_cnt].tp_type = "tcp";
341 tsx_test[tsx_test_cnt].type = PJSIP_TRANSPORT_TCP;
342 ++tsx_test_cnt;
343 } else {
344 app_perror("Unable to create TCP", status);
345 rc = -4;
346 goto on_return;
347 }
Benny Prijono3569c0d2007-04-06 10:29:20 +0000348#endif
Benny Prijonoe93e2872006-06-28 16:46:49 +0000349
350
351 for (i=0; i<tsx_test_cnt; ++i) {
352 DO_TSX_TEST(tsx_basic_test, &tsx_test[i]);
353 DO_TSX_TEST(tsx_uac_test, &tsx_test[i]);
354 DO_TSX_TEST(tsx_uas_test, &tsx_test[i]);
355 }
Benny Prijono02b8fd82006-06-26 15:12:55 +0000356#endif
357
Benny Prijono1f7767b2007-10-03 18:28:49 +0000358#if INCLUDE_INV_OA_TEST
359 DO_TEST(inv_offer_answer_test());
360#endif
361
Benny Prijonodd742da2008-05-17 12:45:00 +0000362#if INCLUDE_REGC_TEST
363 DO_TEST(regc_test());
364#endif
365
Benny Prijono5dcb38d2005-11-21 01:55:47 +0000366
367on_return:
Benny Prijonoe93e2872006-06-28 16:46:49 +0000368 flush_events(500);
Benny Prijono95c63482006-07-06 14:28:45 +0000369
370 /* Dumping memory pool usage */
Benny Prijono1ef06df2006-07-09 10:06:44 +0000371 PJ_LOG(3,(THIS_FILE, "Peak memory size=%u MB",
372 caching_pool.peak_used_size / 1000000));
Benny Prijono95c63482006-07-06 14:28:45 +0000373
Benny Prijono5dcb38d2005-11-21 01:55:47 +0000374 pjsip_endpt_destroy(endpt);
375 pj_caching_pool_destroy(&caching_pool);
376
Benny Prijono85598d92006-01-07 18:44:25 +0000377 PJ_LOG(3,(THIS_FILE, ""));
Benny Prijono5dcb38d2005-11-21 01:55:47 +0000378
379 pj_thread_get_stack_info(pj_thread_this(), &filename, &line);
Benny Prijono85598d92006-01-07 18:44:25 +0000380 PJ_LOG(3,(THIS_FILE, "Stack max usage: %u, deepest: %s:%u",
Benny Prijono5dcb38d2005-11-21 01:55:47 +0000381 pj_thread_get_stack_max_usage(pj_thread_this()),
382 filename, line));
383 if (rc == 0)
Benny Prijono85598d92006-01-07 18:44:25 +0000384 PJ_LOG(3,(THIS_FILE, "Looks like everything is okay!.."));
Benny Prijono5dcb38d2005-11-21 01:55:47 +0000385 else
Benny Prijono85598d92006-01-07 18:44:25 +0000386 PJ_LOG(3,(THIS_FILE, "Test completed with error(s)"));
Benny Prijono5dcb38d2005-11-21 01:55:47 +0000387
Benny Prijonoe93e2872006-06-28 16:46:49 +0000388 report_ival("test-status", rc, "", "Overall test status/result (0==success)");
389 close_report();
Benny Prijono733c67a2006-06-23 01:03:52 +0000390 return rc;
Benny Prijono5dcb38d2005-11-21 01:55:47 +0000391}
392