summaryrefslogtreecommitdiff
path: root/pjsip/src/test
diff options
context:
space:
mode:
authorBenny Prijono <bennylp@teluu.com>2013-03-05 11:59:54 +0000
committerBenny Prijono <bennylp@teluu.com>2013-03-05 11:59:54 +0000
commit22da209226aac2c65f45900e55cf5f162cd311d4 (patch)
tree6ab301e7c4b749be0683e50760c8b50da1c9e5e2 /pjsip/src/test
parent1f3242dc1324388f45e1ed939d7656352dd92f7e (diff)
Implementation of Re #1628: Modify SIP transaction to use group lock to avoid deadlock etc.
git-svn-id: http://svn.pjsip.org/repos/pjproject/trunk@4420 74dad513-b988-da41-8d7b-12977e46ad98
Diffstat (limited to 'pjsip/src/test')
-rw-r--r--pjsip/src/test/regc_test.c5
-rw-r--r--pjsip/src/test/test.c10
-rw-r--r--pjsip/src/test/test.h3
-rw-r--r--pjsip/src/test/tsx_basic_test.c188
-rw-r--r--pjsip/src/test/tsx_bench.c15
-rw-r--r--pjsip/src/test/tsx_uac_test.c13
-rw-r--r--pjsip/src/test/tsx_uas_test.c8
7 files changed, 229 insertions, 13 deletions
diff --git a/pjsip/src/test/regc_test.c b/pjsip/src/test/regc_test.c
index 7a5b8065..17cb399a 100644
--- a/pjsip/src/test/regc_test.c
+++ b/pjsip/src/test/regc_test.c
@@ -347,7 +347,10 @@ static int do_test(const char *title,
client_cfg->error, client_result.error));
return -210;
}
- if (client_result.code != client_cfg->code) {
+ if (client_result.code != client_cfg->code &&
+ client_cfg->code != 502 && client_cfg->code != 503 &&
+ client_result.code != 502 && client_result.code != 503)
+ {
PJ_LOG(3,(THIS_FILE, " error: expecting code=%d, got code=%d",
client_cfg->code, client_result.code));
return -220;
diff --git a/pjsip/src/test/test.c b/pjsip/src/test/test.c
index 8ffe5664..0361e617 100644
--- a/pjsip/src/test/test.c
+++ b/pjsip/src/test/test.c
@@ -47,9 +47,10 @@
pjsip_endpoint *endpt;
+pj_caching_pool caching_pool;
int log_level = 3;
int param_log_decor = PJ_LOG_HAS_NEWLINE | PJ_LOG_HAS_TIME |
- PJ_LOG_HAS_MICRO_SEC;
+ PJ_LOG_HAS_MICRO_SEC | PJ_LOG_HAS_INDENT;
static pj_oshandle_t fd_report;
const char *system_name = "Unknown";
@@ -223,7 +224,6 @@ static void close_report(void)
int test_main(void)
{
pj_status_t rc;
- pj_caching_pool caching_pool;
const char *filename;
unsigned tsx_test_cnt=0;
struct tsx_test_param tsx_test[10];
@@ -369,6 +369,12 @@ int test_main(void)
DO_TEST(regc_test());
#endif
+ /*
+ * Better be last because it recreates the endpt
+ */
+#if INCLUDE_TSX_DESTROY_TEST
+ DO_TEST(tsx_destroy_test());
+#endif
on_return:
flush_events(500);
diff --git a/pjsip/src/test/test.h b/pjsip/src/test/test.h
index 358f9302..690598b9 100644
--- a/pjsip/src/test/test.h
+++ b/pjsip/src/test/test.h
@@ -23,6 +23,7 @@
#include <pjsip/sip_types.h>
extern pjsip_endpoint *endpt;
+extern pj_caching_pool caching_pool;
#define TEST_UDP_PORT 15060
#define TEST_UDP_PORT_STR "15060"
@@ -64,6 +65,7 @@ extern pjsip_endpoint *endpt;
#define INCLUDE_TCP_TEST INCLUDE_TRANSPORT_GROUP
#define INCLUDE_RESOLVE_TEST INCLUDE_TRANSPORT_GROUP
#define INCLUDE_TSX_TEST INCLUDE_TSX_GROUP
+#define INCLUDE_TSX_DESTROY_TEST INCLUDE_TSX_GROUP
#define INCLUDE_INV_OA_TEST INCLUDE_INV_GROUP
#define INCLUDE_REGC_TEST INCLUDE_REGC_GROUP
@@ -75,6 +77,7 @@ int msg_err_test(void);
int multipart_test(void);
int txdata_test(void);
int tsx_bench(void);
+int tsx_destroy_test(void);
int transport_udp_test(void);
int transport_loop_test(void);
int transport_tcp_test(void);
diff --git a/pjsip/src/test/tsx_basic_test.c b/pjsip/src/test/tsx_basic_test.c
index 163c3b9f..2de73d75 100644
--- a/pjsip/src/test/tsx_basic_test.c
+++ b/pjsip/src/test/tsx_basic_test.c
@@ -125,7 +125,7 @@ static int double_terminate(void)
app_perror(" error: unable to terminate transaction", status);
return -40;
}
- pj_mutex_unlock(tsx->mutex);
+ pj_grp_lock_release(tsx->grp_lock);
}
flush_events(500);
@@ -155,3 +155,189 @@ int tsx_basic_test(struct tsx_test_param *param)
return 0;
}
+
+/**************************************************************************/
+
+struct tsx_test_state
+{
+ int pool_cnt;
+};
+
+static void save_tsx_test_state(struct tsx_test_state *st)
+{
+ st->pool_cnt = caching_pool.used_count;
+}
+
+static pj_status_t check_tsx_test_state(struct tsx_test_state *st)
+{
+ if (caching_pool.used_count > st->pool_cnt)
+ return -1;
+
+ return 0;
+}
+
+static void destroy_endpt()
+{
+ pjsip_endpt_destroy(endpt);
+ endpt = NULL;
+}
+
+static pj_status_t init_endpt()
+{
+ pj_str_t ns = { "10.187.27.172", 13}; /* just a random, unreachable IP */
+ pj_dns_resolver *resolver;
+ pj_status_t rc;
+
+ rc = pjsip_endpt_create(&caching_pool.factory, "endpt", &endpt);
+ if (rc != PJ_SUCCESS) {
+ app_perror("pjsip_endpt_create", rc);
+ return rc;
+ }
+
+ /* Start transaction layer module. */
+ rc = pjsip_tsx_layer_init_module(endpt);
+ if (rc != PJ_SUCCESS) {
+ app_perror("tsx_layer_init", rc);
+ return rc;
+ }
+
+ rc = pjsip_udp_transport_start(endpt, NULL, NULL, 1, NULL);
+ if (rc != PJ_SUCCESS) {
+ app_perror("udp init", rc);
+ return rc;
+ }
+
+ rc = pjsip_tcp_transport_start(endpt, NULL, 1, NULL);
+ if (rc != PJ_SUCCESS) {
+ app_perror("tcp init", rc);
+ return rc;
+ }
+
+ rc = pjsip_endpt_create_resolver(endpt, &resolver);
+ if (rc != PJ_SUCCESS) {
+ app_perror("create resolver", rc);
+ return rc;
+ }
+
+ pj_dns_resolver_set_ns(resolver, 1, &ns, NULL);
+
+ rc = pjsip_endpt_set_resolver(endpt, resolver);
+ if (rc != PJ_SUCCESS) {
+ app_perror("set resolver", rc);
+ return rc;
+ }
+
+ return PJ_SUCCESS;
+}
+
+static int tsx_create_and_send_req(void *arg)
+{
+ pj_str_t dst_uri = pj_str((char*)arg);
+ pj_str_t from_uri = pj_str((char*)"<sip:user@host>");
+ pjsip_tx_data *tdata;
+ pj_status_t status;
+
+ status = pjsip_endpt_create_request(endpt, &pjsip_options_method,
+ &dst_uri, &from_uri, &dst_uri,
+ NULL, NULL, -1, NULL,
+ &tdata);
+ if (status != PJ_SUCCESS)
+ return status;
+
+ status = pjsip_endpt_send_request(endpt, tdata, -1, NULL, NULL);
+ if (status != PJ_SUCCESS)
+ return status;
+
+ return PJ_SUCCESS;
+}
+
+int tsx_destroy_test()
+{
+ struct tsx_test_state state;
+ struct test_desc
+ {
+ const char *title;
+ int (*func)(void*);
+ void *arg;
+ int sleep_before_unload;
+ int sleep_after_unload;
+ } test_entries[] =
+ {
+ {
+ "normal unable to resolve",
+ &tsx_create_and_send_req,
+ "sip:user@somehost",
+ 10000,
+ 1
+ },
+ {
+ "resolve and destroy, wait",
+ &tsx_create_and_send_req,
+ "sip:user@somehost",
+ 1,
+ 10000
+ },
+ {
+ "tcp connect and destroy",
+ &tsx_create_and_send_req,
+ "sip:user@10.125.36.63:58517;transport=tcp",
+ 60000,
+ 1000
+ },
+ {
+ "tcp connect and destroy",
+ &tsx_create_and_send_req,
+ "sip:user@10.125.36.63:58517;transport=tcp",
+ 1,
+ 60000
+ },
+
+ };
+ int rc;
+ unsigned i;
+ const int INDENT = 2;
+
+ pj_log_add_indent(INDENT);
+ destroy_endpt();
+
+ for (i=0; i<PJ_ARRAY_SIZE(test_entries); ++i) {
+ struct test_desc *td = &test_entries[i];
+
+ PJ_LOG(3,(THIS_FILE, "%s", td->title));
+
+ pj_log_add_indent(INDENT);
+ save_tsx_test_state(&state);
+
+ rc = init_endpt();
+ if (rc != PJ_SUCCESS) {
+ pj_log_add_indent(-INDENT*2);
+ return -10;
+ }
+
+ rc = td->func(td->arg);
+ if (rc != PJ_SUCCESS) {
+ pj_log_add_indent(-INDENT*2);
+ return -20;
+ }
+
+ flush_events(td->sleep_before_unload);
+ pjsip_tsx_layer_destroy();
+ flush_events(td->sleep_after_unload);
+ destroy_endpt();
+
+ rc = check_tsx_test_state(&state);
+ if (rc != PJ_SUCCESS) {
+ init_endpt();
+ pj_log_add_indent(-INDENT*2);
+ return -30;
+ }
+
+ pj_log_add_indent(-INDENT);
+ }
+
+ init_endpt();
+
+ pj_log_add_indent(-INDENT);
+ return 0;
+}
+
diff --git a/pjsip/src/test/tsx_bench.c b/pjsip/src/test/tsx_bench.c
index 8ae57783..2282b6a9 100644
--- a/pjsip/src/test/tsx_bench.c
+++ b/pjsip/src/test/tsx_bench.c
@@ -79,8 +79,13 @@ static int uac_tsx_bench(unsigned working_set, pj_timestamp *p_elapsed)
on_error:
for (i=0; i<working_set; ++i) {
if (tsx[i]) {
+ pj_timer_heap_t *th;
+
pjsip_tsx_terminate(tsx[i], 601);
tsx[i] = NULL;
+
+ th = pjsip_endpt_get_timer_heap(endpt);
+ pj_timer_heap_poll(th, NULL);
}
}
pjsip_tx_data_dec_ref(request);
@@ -177,8 +182,14 @@ static int uas_tsx_bench(unsigned working_set, pj_timestamp *p_elapsed)
on_error:
for (i=0; i<working_set; ++i) {
if (tsx[i]) {
+ pj_timer_heap_t *th;
+
pjsip_tsx_terminate(tsx[i], 601);
tsx[i] = NULL;
+
+ th = pjsip_endpt_get_timer_heap(endpt);
+ pj_timer_heap_poll(th, NULL);
+
}
}
pjsip_tx_data_dec_ref(request);
@@ -208,6 +219,8 @@ int tsx_bench(void)
for (i=0; i<REPEAT; ++i) {
PJ_LOG(3,(THIS_FILE, " test %d of %d..",
i+1, REPEAT));
+ PJ_LOG(3,(THIS_FILE, " number of current tsx: %d",
+ pjsip_tsx_layer_get_tsx_count()));
status = uac_tsx_bench(WORKING_SET, &usec[i]);
if (status != PJ_SUCCESS)
return status;
@@ -246,6 +259,8 @@ int tsx_bench(void)
for (i=0; i<REPEAT; ++i) {
PJ_LOG(3,(THIS_FILE, " test %d of %d..",
i+1, REPEAT));
+ PJ_LOG(3,(THIS_FILE, " number of current tsx: %d",
+ pjsip_tsx_layer_get_tsx_count()));
status = uas_tsx_bench(WORKING_SET, &usec[i]);
if (status != PJ_SUCCESS)
return status;
diff --git a/pjsip/src/test/tsx_uac_test.c b/pjsip/src/test/tsx_uac_test.c
index 0677da18..d978df80 100644
--- a/pjsip/src/test/tsx_uac_test.c
+++ b/pjsip/src/test/tsx_uac_test.c
@@ -220,10 +220,13 @@ static void tsx_user_on_tsx_state(pjsip_transaction *tsx, pjsip_event *e)
if (tsx->state == PJSIP_TSX_STATE_TERMINATED) {
/* Test the status code. */
- if (tsx->status_code != PJSIP_SC_TSX_TRANSPORT_ERROR) {
+ if (tsx->status_code != PJSIP_SC_TSX_TRANSPORT_ERROR &&
+ tsx->status_code != PJSIP_SC_BAD_GATEWAY)
+ {
PJ_LOG(3,(THIS_FILE,
- " error: status code is %d instead of %d",
- tsx->status_code, PJSIP_SC_TSX_TRANSPORT_ERROR));
+ " error: status code is %d instead of %d or %d",
+ tsx->status_code, PJSIP_SC_TSX_TRANSPORT_ERROR,
+ PJSIP_SC_BAD_GATEWAY));
test_complete = -720;
}
@@ -688,7 +691,7 @@ static pj_bool_t msg_receiver_on_rx_request(pjsip_rx_data *rdata)
tsx = pjsip_tsx_layer_find_tsx(&key, PJ_TRUE);
if (tsx) {
pjsip_tsx_terminate(tsx, PJSIP_SC_REQUEST_TERMINATED);
- pj_mutex_unlock(tsx->mutex);
+ pj_grp_lock_release(tsx->grp_lock);
} else {
PJ_LOG(3,(THIS_FILE, " error: uac transaction not found!"));
test_complete = -633;
@@ -1027,7 +1030,7 @@ static int perform_tsx_test(int dummy, char *target_uri, char *from_uri,
tsx = pjsip_tsx_layer_find_tsx(&tsx_key, PJ_TRUE);
if (tsx) {
pjsip_tsx_terminate(tsx, PJSIP_SC_REQUEST_TERMINATED);
- pj_mutex_unlock(tsx->mutex);
+ pj_grp_lock_release(tsx->grp_lock);
flush_events(1000);
}
pjsip_tx_data_dec_ref(tdata);
diff --git a/pjsip/src/test/tsx_uas_test.c b/pjsip/src/test/tsx_uas_test.c
index 973f3315..3c43f535 100644
--- a/pjsip/src/test/tsx_uas_test.c
+++ b/pjsip/src/test/tsx_uas_test.c
@@ -225,12 +225,12 @@ static void send_response_timer( pj_timer_heap_t *timer_heap,
if (status != PJ_SUCCESS) {
// Some tests do expect failure!
//PJ_LOG(3,(THIS_FILE," error: timer unable to send response"));
- pj_mutex_unlock(tsx->mutex);
+ pj_grp_lock_release(tsx->grp_lock);
pjsip_tx_data_dec_ref(r->tdata);
return;
}
- pj_mutex_unlock(tsx->mutex);
+ pj_grp_lock_release(tsx->grp_lock);
}
/* Utility to send response. */
@@ -313,7 +313,7 @@ static void terminate_our_tsx(int status_code)
}
pjsip_tsx_terminate(tsx, status_code);
- pj_mutex_unlock(tsx->mutex);
+ pj_grp_lock_release(tsx->grp_lock);
}
#if 0 /* Unused for now */
@@ -1259,7 +1259,7 @@ static int perform_test( char *target_uri, char *from_uri,
tsx = pjsip_tsx_layer_find_tsx(&tsx_key, PJ_TRUE);
if (tsx) {
pjsip_tsx_terminate(tsx, PJSIP_SC_REQUEST_TERMINATED);
- pj_mutex_unlock(tsx->mutex);
+ pj_grp_lock_release(tsx->grp_lock);
flush_events(1000);
}
pjsip_tx_data_dec_ref(tdata);