diff options
author | Benny Prijono <bennylp@teluu.com> | 2006-01-18 23:34:15 +0000 |
---|---|---|
committer | Benny Prijono <bennylp@teluu.com> | 2006-01-18 23:34:15 +0000 |
commit | 3a125b4c3b0d5aedb30d5ca8088f6f5b4b33caf5 (patch) | |
tree | dd519ac8366416811627ad3ddb9d0ab4e9004594 /pjsip/src/test-pjsip | |
parent | d192c694c8bf65798b042853a23932d08dc806a1 (diff) |
Complete tsx layer selftest, implemented authentication framework
git-svn-id: http://svn.pjsip.org/repos/pjproject/trunk@123 74dad513-b988-da41-8d7b-12977e46ad98
Diffstat (limited to 'pjsip/src/test-pjsip')
-rw-r--r-- | pjsip/src/test-pjsip/transport_test.c | 12 | ||||
-rw-r--r-- | pjsip/src/test-pjsip/tsx_uac_test.c | 16 | ||||
-rw-r--r-- | pjsip/src/test-pjsip/tsx_uas_test.c | 369 | ||||
-rw-r--r-- | pjsip/src/test-pjsip/txdata_test.c | 2 |
4 files changed, 336 insertions, 63 deletions
diff --git a/pjsip/src/test-pjsip/transport_test.c b/pjsip/src/test-pjsip/transport_test.c index b57fedbf..74f6d796 100644 --- a/pjsip/src/test-pjsip/transport_test.c +++ b/pjsip/src/test-pjsip/transport_test.c @@ -116,7 +116,7 @@ static pjsip_module my_module = static pj_bool_t my_on_rx_request(pjsip_rx_data *rdata) { /* Check that this is our request. */ - if (pj_strcmp2(&rdata->msg_info.call_id, CALL_ID_HDR) == 0) { + if (pj_strcmp2(&rdata->msg_info.cid->id, CALL_ID_HDR) == 0) { /* It is! */ /* Send response. */ pjsip_tx_data *tdata; @@ -149,7 +149,7 @@ static pj_bool_t my_on_rx_request(pjsip_rx_data *rdata) static pj_bool_t my_on_rx_response(pjsip_rx_data *rdata) { - if (pj_strcmp2(&rdata->msg_info.call_id, CALL_ID_HDR) == 0) { + if (pj_strcmp2(&rdata->msg_info.cid->id, CALL_ID_HDR) == 0) { pj_get_timestamp(&my_recv_time); recv_status = PJ_SUCCESS; return PJ_TRUE; @@ -334,8 +334,8 @@ static pj_str_t rt_call_id; static pj_bool_t rt_on_rx_request(pjsip_rx_data *rdata) { - if (!pj_strncmp(&rdata->msg_info.call_id, &rt_call_id, rt_call_id.slen)) { - char *pos = pj_strchr(&rdata->msg_info.call_id, '/'); + if (!pj_strncmp(&rdata->msg_info.cid->id, &rt_call_id, rt_call_id.slen)) { + char *pos = pj_strchr(&rdata->msg_info.cid->id, '/'); int thread_id = (*pos - '0'); pjsip_tx_data *tdata; @@ -422,8 +422,8 @@ static pj_status_t rt_send_request(int thread_id) static pj_bool_t rt_on_rx_response(pjsip_rx_data *rdata) { - if (!pj_strncmp(&rdata->msg_info.call_id, &rt_call_id, rt_call_id.slen)) { - char *pos = pj_strchr(&rdata->msg_info.call_id, '/')+1; + if (!pj_strncmp(&rdata->msg_info.cid->id, &rt_call_id, rt_call_id.slen)) { + char *pos = pj_strchr(&rdata->msg_info.cid->id, '/')+1; int thread_id = (*pos - '0'); pj_timestamp recv_time; diff --git a/pjsip/src/test-pjsip/tsx_uac_test.c b/pjsip/src/test-pjsip/tsx_uac_test.c index 182269cd..2ec94e5a 100644 --- a/pjsip/src/test-pjsip/tsx_uac_test.c +++ b/pjsip/src/test-pjsip/tsx_uac_test.c @@ -398,12 +398,14 @@ static void tsx_user_on_tsx_state(pjsip_transaction *tsx, pjsip_event *e) test_complete = -747; } - /* last_tx is ACK in this case. */ + /* last_tx MUST be the INVITE request + * (authorization depends on this behavior) + */ if (tsx->last_tx && tsx->last_tx->msg->line.req.method.id != - PJSIP_ACK_METHOD) + PJSIP_INVITE_METHOD) { PJ_LOG(3,(THIS_FILE, - " error: last_tx is not ACK")); + " error: last_tx is not INVITE")); test_complete = -748; } } @@ -461,12 +463,14 @@ static void tsx_user_on_tsx_state(pjsip_transaction *tsx, pjsip_event *e) test_complete = -763; } - /* last_tx is ACK in this case. */ + /* last_tx MUST be INVITE. + * (authorization depends on this behavior) + */ if (tsx->last_tx && tsx->last_tx->msg->line.req.method.id != - PJSIP_ACK_METHOD) + PJSIP_INVITE_METHOD) { PJ_LOG(3,(THIS_FILE, - " error: last_tx is not ACK")); + " error: last_tx is not INVITE")); test_complete = -764; } diff --git a/pjsip/src/test-pjsip/tsx_uas_test.c b/pjsip/src/test-pjsip/tsx_uas_test.c index bed6fd08..ecc174c4 100644 --- a/pjsip/src/test-pjsip/tsx_uas_test.c +++ b/pjsip/src/test-pjsip/tsx_uas_test.c @@ -66,10 +66,19 @@ ** until it's terminated by user). ** Transaction also MUST terminate in T4 seconds. ** - ** TEST10_BRANCH_ID - ** Test where INVITE UAS transaction never receives ACK - ** ** TEST11_BRANCH_ID + ** Test scenario where transport fails before response is sent (i.e. + ** in TRYING state). + ** + ** TEST12_BRANCH_ID + ** As above, after provisional response is sent but before final + ** response is sent (i.e. in PROCEEDING state). + ** + ** TEST13_BRANCH_ID + ** As above, for INVITE, after final response has been sent but before + ** ACK is received (i.e. in CONNECTED state). + ** + ** TEST14_BRANCH_ID ** When UAS failed to deliver the response with the selected transport, ** it should try contacting the client with other transport or begin ** RFC 3263 server resolution procedure. @@ -79,11 +88,6 @@ ** upon receiving request retransmission). ** c. COMPLETED state. ** - ** TEST12_BRANCH_ID - ** Variant of previous test, where transaction fails to deliver the - ** response using any kind of transports. Transaction should report - ** transport error to its transaction user. - ** **/ static char *TEST1_BRANCH_ID = PJSIP_RFC3261_BRANCH_ID "-UAS-Test1"; @@ -98,6 +102,7 @@ static char *TEST9_BRANCH_ID = PJSIP_RFC3261_BRANCH_ID "-UAS-Test9"; static char *TEST10_BRANCH_ID = PJSIP_RFC3261_BRANCH_ID "-UAS-Test10"; static char *TEST11_BRANCH_ID = PJSIP_RFC3261_BRANCH_ID "-UAS-Test11"; static char *TEST12_BRANCH_ID = PJSIP_RFC3261_BRANCH_ID "-UAS-Test12"; +static char *TEST13_BRANCH_ID = PJSIP_RFC3261_BRANCH_ID "-UAS-Test13"; #define TEST1_STATUS_CODE 200 #define TEST2_STATUS_CODE 301 @@ -115,6 +120,7 @@ static char *TEST12_BRANCH_ID = PJSIP_RFC3261_BRANCH_ID "-UAS-Test12"; #define TEST6_RESPONSE_COUNT 3 #define TEST7_STATUS_CODE 301 #define TEST8_STATUS_CODE 302 +#define TEST9_STATUS_CODE 301 #define TEST4_TITLE "test4: absorbing request retransmission" @@ -210,10 +216,14 @@ static void send_response_timer( pj_timer_heap_t *timer_heap, status = pjsip_tsx_send_msg(tsx, r->tdata); if (status != PJ_SUCCESS) { - PJ_LOG(3,(THIS_FILE," error: timer unable to send response")); + // Some tests do expect failure! + //PJ_LOG(3,(THIS_FILE," error: timer unable to send response")); + pj_mutex_unlock(tsx->mutex); pjsip_tx_data_dec_ref(r->tdata); return; } + + pj_mutex_unlock(tsx->mutex); } /* Utility to send response. */ @@ -234,9 +244,10 @@ static void send_response( pjsip_rx_data *rdata, status = pjsip_tsx_send_msg(tsx, tdata); if (status != PJ_SUCCESS) { - app_perror(" error: unable to send response", status); pjsip_tx_data_dec_ref(tdata); - test_complete = -197; + // Some tests do expect failure! + //app_perror(" error: unable to send response", status); + //test_complete = -197; return; } } @@ -249,6 +260,7 @@ static void schedule_send_response( pjsip_rx_data *rdata, { pj_status_t status; pjsip_tx_data *tdata; + pj_timer_entry *t; struct response *r; pj_time_val delay; @@ -268,14 +280,15 @@ static void schedule_send_response( pjsip_rx_data *rdata, delay.msec = msec_delay; pj_time_val_normalize(&delay); - timer.user_data = r; - timer.cb = &send_response_timer; + t = pj_pool_zalloc(tdata->pool, sizeof(*t)); + t->user_data = r; + t->cb = &send_response_timer; - status = pjsip_endpt_schedule_timer(endpt, &timer, &delay); + status = pjsip_endpt_schedule_timer(endpt, t, &delay); if (status != PJ_SUCCESS) { + pjsip_tx_data_dec_ref(tdata); app_perror(" error: unable to schedule timer", status); test_complete = -199; - pjsip_tx_data_dec_ref(tdata); return; } } @@ -574,6 +587,83 @@ static void tsx_user_on_tsx_state(pjsip_transaction *tsx, pjsip_event *e) } + + } else + if (pj_strcmp2(&tsx->branch, TEST9_BRANCH_ID)==0) { + /* + * TEST9_BRANCH_ID tests that retransmission of INVITE final response + * must cease when ACK is received. + */ + + if (tsx->state == PJSIP_TSX_STATE_TERMINATED) { + + if (test_complete == 0) + test_complete = 1; + + /* Check status code. */ + if (tsx->status_code != TEST9_STATUS_CODE) { + PJ_LOG(3,(THIS_FILE, " error: incorrect status code")); + test_complete = -160; + } + + /* Previous state. */ + if (e->body.tsx_state.prev_state != PJSIP_TSX_STATE_CONFIRMED) { + PJ_LOG(3,(THIS_FILE, " error: incorrect prev_state")); + test_complete = -161; + } + + } else if (tsx->state == PJSIP_TSX_STATE_COMPLETED) { + + /* Check that status code is status_code. */ + if (tsx->status_code != TEST9_STATUS_CODE) { + PJ_LOG(3,(THIS_FILE, " error: incorrect status code")); + test_complete = -162; + } + + /* Previous state. */ + if (e->body.tsx_state.prev_state != PJSIP_TSX_STATE_TRYING) { + PJ_LOG(3,(THIS_FILE, " error: incorrect prev_state")); + test_complete = -163; + } + + + } else if (tsx->state == PJSIP_TSX_STATE_CONFIRMED) { + + /* Check that status code is status_code. */ + if (tsx->status_code != TEST9_STATUS_CODE) { + PJ_LOG(3,(THIS_FILE, " error: incorrect status code")); + test_complete = -164; + } + + /* Previous state. */ + if (e->body.tsx_state.prev_state != PJSIP_TSX_STATE_COMPLETED) { + PJ_LOG(3,(THIS_FILE, " error: incorrect prev_state")); + test_complete = -165; + } + + } else if (tsx->state != PJSIP_TSX_STATE_DESTROYED) { + + PJ_LOG(3,(THIS_FILE, " error: unexpected state")); + test_complete = -166; + + } + + + } else + if (pj_strcmp2(&tsx->branch, TEST10_BRANCH_ID)==0 || + pj_strcmp2(&tsx->branch, TEST11_BRANCH_ID)==0 || + pj_strcmp2(&tsx->branch, TEST12_BRANCH_ID)==0) + { + if (tsx->state == PJSIP_TSX_STATE_TERMINATED) { + + if (!test_complete) + test_complete = 1; + + if (tsx->status_code != PJSIP_SC_TSX_TRANSPORT_ERROR) { + PJ_LOG(3,(THIS_FILE," error: incorrect status code")); + test_complete = -170; + } + } } } @@ -612,7 +702,7 @@ static pj_bool_t on_rx_message(pjsip_rx_data *rdata) TEST1_STATUS_CODE : TEST2_STATUS_CODE; if (msg->type == PJSIP_REQUEST_MSG) { - /* On received response, create UAS and respond with final + /* On received request, create UAS and respond with final * response. */ pjsip_transaction *tsx; @@ -652,7 +742,7 @@ static pj_bool_t on_rx_message(pjsip_rx_data *rdata) /* TEST3_BRANCH_ID tests provisional response. */ if (msg->type == PJSIP_REQUEST_MSG) { - /* On received response, create UAS and respond with provisional + /* On received request, create UAS and respond with provisional * response, then schedule timer to send final response. */ pjsip_transaction *tsx; @@ -705,7 +795,7 @@ static pj_bool_t on_rx_message(pjsip_rx_data *rdata) /* TEST6_BRANCH_ID: retransmit last response in COMPLETED state. */ if (msg->type == PJSIP_REQUEST_MSG) { - /* On received response, create UAS. */ + /* On received request, create UAS. */ pjsip_transaction *tsx; status = pjsip_tsx_create_uas(&tsx_user, rdata, &tsx); @@ -786,7 +876,7 @@ static pj_bool_t on_rx_message(pjsip_rx_data *rdata) */ if (msg->type == PJSIP_REQUEST_MSG) { - /* On received response, create UAS. */ + /* On received request, create UAS. */ pjsip_transaction *tsx; status = pjsip_tsx_create_uas(&tsx_user, rdata, &tsx); @@ -861,7 +951,7 @@ static pj_bool_t on_rx_message(pjsip_rx_data *rdata) } return PJ_TRUE; - } else if (pj_strcmp2(&branch_param, TEST9_BRANCH_ID)) { + } else if (pj_strcmp2(&branch_param, TEST9_BRANCH_ID) == 0) { /* * TEST9_BRANCH_ID tests that the retransmission of INVITE final @@ -870,49 +960,36 @@ static pj_bool_t on_rx_message(pjsip_rx_data *rdata) */ if (msg->type == PJSIP_REQUEST_MSG) { - /* On received response, create UAS. */ + /* On received request, create UAS. */ pjsip_transaction *tsx; status = pjsip_tsx_create_uas(&tsx_user, rdata, &tsx); if (status != PJ_SUCCESS) { app_perror(" error: unable to create transaction", status); - test_complete = -140; + test_complete = -150; return PJ_TRUE; } save_key(tsx); + send_response(rdata, tsx, TEST9_STATUS_CODE); - if (pj_strcmp2(&branch_param, TEST7_BRANCH_ID) == 0) { - - send_response(rdata, tsx, TEST7_STATUS_CODE); - - } else { - - send_response(rdata, tsx, TEST8_STATUS_CODE); - - } } else { - int code; ++recv_count; - if (pj_strcmp2(&branch_param, TEST7_BRANCH_ID) == 0) - code = TEST7_STATUS_CODE; - else - code = TEST8_STATUS_CODE; + if (rdata->msg_info.msg->line.status.code != TEST9_STATUS_CODE) { + PJ_LOG(3,(THIS_FILE," error: invalid status code")); + test_complete = -151; + } if (recv_count==1) { - - if (rdata->msg_info.msg->line.status.code != code) { - PJ_LOG(3,(THIS_FILE," error: invalid status code")); - test_complete = -141; - } recv_last = rdata->pkt_info.timestamp; - } else { + } else if (recv_count < 5) { + /* Let UAS retransmit some messages before we send ACK. */ pj_time_val now; unsigned msec, msec_expected; @@ -930,19 +1007,90 @@ static pj_bool_t on_rx_message(pjsip_rx_data *rdata) " error: incorrect retransmission " "time (%d ms expected, %d ms received", msec_expected, msec)); - test_complete = -142; + test_complete = -152; } - if (recv_count > 11) { - PJ_LOG(3,(THIS_FILE," error: too many responses (%d)", - recv_count)); - test_complete = -143; + recv_last = rdata->pkt_info.timestamp; + + } else if (recv_count == 5) { + pjsip_tx_data *tdata; + pjsip_sip_uri *uri; + pjsip_via_hdr *via; + + status = pjsip_endpt_create_request_from_hdr( + endpt, &pjsip_ack_method, + rdata->msg_info.to->uri, + rdata->msg_info.from, + rdata->msg_info.to, + NULL, + rdata->msg_info.cid, + rdata->msg_info.cseq->cseq, + NULL, + &tdata); + if (status != PJ_SUCCESS) { + app_perror(" error: unable to create ACK", status); + test_complete = -153; + return PJ_TRUE; } - recv_last = rdata->pkt_info.timestamp; + uri=(pjsip_sip_uri*)pjsip_uri_get_uri(tdata->msg->line.req.uri); + uri->transport_param = pj_str("loop-dgram"); + + via = pjsip_msg_find_hdr(tdata->msg, PJSIP_H_VIA, NULL); + via->branch_param = pj_str(TEST9_BRANCH_ID); + + status = pjsip_endpt_send_request_stateless(endpt, tdata, + NULL, NULL); + if (status != PJ_SUCCESS) { + app_perror(" error: unable to send ACK", status); + test_complete = -154; + } + + } else { + PJ_LOG(3,(THIS_FILE," error: too many responses (%d)", + recv_count)); + test_complete = -155; + } + + } + return PJ_TRUE; + + } else if (pj_strcmp2(&branch_param, TEST10_BRANCH_ID) == 0 || + pj_strcmp2(&branch_param, TEST11_BRANCH_ID) == 0 || + pj_strcmp2(&branch_param, TEST12_BRANCH_ID) == 0) + { + int test_num, code1, code2; + + if (pj_strcmp2(&branch_param, TEST10_BRANCH_ID) == 0) + test_num=10, code1 = 100, code2 = 0; + else if (pj_strcmp2(&branch_param, TEST11_BRANCH_ID) == 0) + test_num=11, code1 = 100, code2 = 200; + else + test_num=12, code1 = 200, code2 = 0; + + if (rdata->msg_info.msg->type == PJSIP_REQUEST_MSG) { + + /* On received response, create UAS. */ + pjsip_transaction *tsx; + + status = pjsip_tsx_create_uas(&tsx_user, rdata, &tsx); + if (status != PJ_SUCCESS) { + app_perror(" error: unable to create transaction", status); + test_complete = -150; + return PJ_TRUE; } + save_key(tsx); + + schedule_send_response(rdata, &tsx_key, code1, 1000); + + if (code2) + schedule_send_response(rdata, &tsx_key, code2, 2000); + + } else { + } + return PJ_TRUE; } @@ -1212,6 +1360,113 @@ static int tsx_final_response_retransmission_test(void) } +/***************************************************************************** + ** + ** TEST9_BRANCH_ID: retransmission of non-2xx INVITE final response must + ** cease when ACK is received + ** + ***************************************************************************** + */ +static int tsx_ack_test(void) +{ + int status; + + PJ_LOG(3,(THIS_FILE, + " test9: receiving ACK for non-2xx final response")); + + status = perform_test("sip:129.0.0.1;transport=loop-dgram", + "sip:129.0.0.1;transport=loop-dgram", + TEST9_BRANCH_ID, + 20, /* allow 5 retransmissions */ + &pjsip_invite_method, 1, 0, 0); + if (status != 0) + return status; + + + return 0; +} + + + +/***************************************************************************** + ** + ** TEST10_BRANCH_ID: test transport failure in TRYING state. + ** TEST11_BRANCH_ID: test transport failure in PROCEEDING state. + ** TEST12_BRANCH_ID: test transport failure in CONNECTED state. + ** TEST13_BRANCH_ID: test transport failure in CONFIRMED state. + ** + ***************************************************************************** + */ +static int tsx_transport_failure_test(void) +{ + struct test_desc + { + int transport_delay; + int fail_delay; + char *branch_id; + char *title; + } tests[] = + { + { 0, 10, TEST10_BRANCH_ID, "test10: failed transport in TRYING state (no delay)" }, + { 50, 10, TEST10_BRANCH_ID, "test10: failed transport in TRYING state (50 ms delay)" }, + { 0, 1500, TEST11_BRANCH_ID, "test11: failed transport in PROCEEDING state (no delay)" }, + { 50, 1500, TEST11_BRANCH_ID, "test11: failed transport in PROCEEDING state (50 ms delay)" }, + { 0, 2500, TEST12_BRANCH_ID, "test12: failed transport in COMPLETED state (no delay)" }, + { 50, 2500, TEST12_BRANCH_ID, "test12: failed transport in COMPLETED state (50 ms delay)" }, + }; + int i, status; + + for (i=0; i<PJ_ARRAY_SIZE(tests); ++i) { + pj_time_val fail_time, end_test, now; + + PJ_LOG(3,(THIS_FILE, " %s", tests[i].title)); + pjsip_loop_set_failure(loop, 0, NULL); + pjsip_loop_set_delay(loop, tests[i].transport_delay); + + status = perform_test("sip:129.0.0.1;transport=loop-dgram", + "sip:129.0.0.1;transport=loop-dgram", + tests[i].branch_id, + 0, + &pjsip_invite_method, 1, 0, 1); + if (status && status != TEST_TIMEOUT_ERROR) + return status; + if (!status) { + PJ_LOG(3,(THIS_FILE, " error: expecting timeout")); + return -40; + } + + pj_gettimeofday(&fail_time); + fail_time.msec += tests[i].fail_delay; + pj_time_val_normalize(&fail_time); + + do { + pj_time_val interval = { 0, 1 }; + pj_gettimeofday(&now); + pjsip_endpt_handle_events(endpt, &interval); + } while (PJ_TIME_VAL_LT(now, fail_time)); + + pjsip_loop_set_failure(loop, 1, NULL); + + end_test = now; + end_test.sec += 5; + + do { + pj_time_val interval = { 0, 1 }; + pj_gettimeofday(&now); + pjsip_endpt_handle_events(endpt, &interval); + } while (!test_complete && PJ_TIME_VAL_LT(now, end_test)); + + if (test_complete == 0) { + PJ_LOG(3,(THIS_FILE, " error: test has timed out")); + return -41; + } + + if (test_complete != 1) + return test_complete; + } + + return 0; +} /***************************************************************************** ** @@ -1244,7 +1499,6 @@ int tsx_uas_test(void) return -4; } -#if 0 /* TEST1_BRANCH_ID: Basic 2xx final response. * TEST2_BRANCH_ID: Basic non-2xx final response. */ @@ -1293,7 +1547,22 @@ int tsx_uas_test(void) if (status != 0) return status; -#endif + /* TEST9_BRANCH_ID: retransmission of non-2xx INVITE final response must + * cease when ACK is received + */ + status = tsx_ack_test(); + if (status != 0) + return status; + + /* TEST10_BRANCH_ID: test transport failure in TRYING state. + * TEST11_BRANCH_ID: test transport failure in PROCEEDING state. + * TEST12_BRANCH_ID: test transport failure in CONNECTED state. + * TEST13_BRANCH_ID: test transport failure in CONFIRMED state. + */ + status = tsx_transport_failure_test(); + if (status != 0) + return status; + pjsip_transport_dec_ref(loop); return 0; diff --git a/pjsip/src/test-pjsip/txdata_test.c b/pjsip/src/test-pjsip/txdata_test.c index def46b5a..327ea084 100644 --- a/pjsip/src/test-pjsip/txdata_test.c +++ b/pjsip/src/test-pjsip/txdata_test.c @@ -154,7 +154,7 @@ static int core_txdata_test(void) * We should never do this in real application, as there are many * many more fields need to be initialized!! */ - dummy_rdata.msg_info.call_id = (HFIND(invite->msg, cid, CALL_ID))->id; + dummy_rdata.msg_info.cid = HFIND(invite->msg, cid, CALL_ID); dummy_rdata.msg_info.clen = NULL; dummy_rdata.msg_info.cseq = HFIND(invite->msg, cseq, CSEQ); dummy_rdata.msg_info.ctype = NULL; |