Ignore:
Timestamp:
Jan 7, 2006 6:44:25 PM (18 years ago)
Author:
bennylp
Message:

Added test functions for UAC transaction

File:
1 edited

Legend:

Unmodified
Added
Removed
  • pjproject/trunk/pjsip/src/test-pjsip/tsx_uac_test.c

    r107 r109  
    2222#include <pjlib.h> 
    2323 
     24#define THIS_FILE   "tsx_uac_test.c" 
     25 
     26 
    2427/***************************************************************************** 
    2528 ** 
    26  ** UAC basic retransmission and timeout test. 
    27  ** 
    28  ** This will test the retransmission of the UAC transaction. Remote will not 
    29  ** answer the transaction, so the transaction should fail. 
    30  ** 
     29 ** UAC tests. 
     30 ** 
     31 ** This file performs various tests for UAC transactions. Each test will have 
     32 ** a different Via branch param so that message receiver module and  
     33 ** transaction user module can identify which test is being carried out. 
     34 ** 
     35 ** TEST1_BRANCH_ID 
     36 **     Perform basic retransmission and timeout test. Message receiver will 
     37 **     verify that retransmission is received at correct time. 
     38 **     This test verifies the following requirements: 
     39 **         - retransmit timer doubles for INVITE 
     40 **         - retransmit timer doubles and caps off for non-INVITE 
     41 **         - retransmit timer timer is precise 
     42 **         - correct timeout and retransmission count 
     43 **     Requirements not tested: 
     44 **         - retransmit timer only starts after resolving has completed. 
     45 ** 
     46 ** TEST2_BRANCH_ID 
     47 **     Test scenario where resolver is unable to resolve destination host. 
     48 ** 
     49 ** TEST3_BRANCH_ID 
     50 **     Test scenario where transaction is terminated while resolver is still 
     51 **     running. 
     52 ** 
     53 ** TEST4_BRANCH_ID 
     54 **     Test scenario where transport failed after several retransmissions. 
     55 ** 
     56 ** TEST5_BRANCH_ID 
     57 **     Test scenario where transaction is terminated by user after several 
     58 **     retransmissions. 
     59 ** 
     60 ** TEST6_BRANCH_ID 
     61 **     Test successfull non-INVITE transaction. 
     62 **     It tests the following requirements: 
     63 **         - transaction correctly moves to COMPLETED state. 
     64 **         - retransmission must cease. 
     65 **         - tx_data must be maintained until state is terminated. 
     66 ** 
     67 ** TEST7_BRANCH_ID 
     68 **     Test successfull non-INVITE transaction, with provisional response. 
     69 ** 
     70 ** TEST8_BRANCH_ID 
     71 **     Test failed INVITE transaction (e.g. ACK must be received) 
     72 ** 
     73 ** TEST9_BRANCH_ID 
     74 **     Test failed INVITE transaction with provisional response. 
     75 ** 
     76 **      
    3177 ***************************************************************************** 
    3278 */ 
    3379 
    34 static char *CALL_ID1 = "UAC-Tsx-Basic-Test1"; 
     80static char *TEST1_BRANCH_ID = PJSIP_RFC3261_BRANCH_ID "-Test1"; 
     81static char *TEST2_BRANCH_ID = PJSIP_RFC3261_BRANCH_ID "-Test2"; 
     82static char *TEST3_BRANCH_ID = PJSIP_RFC3261_BRANCH_ID "-Test3"; 
     83static char *TEST4_BRANCH_ID = PJSIP_RFC3261_BRANCH_ID "-Test4"; 
     84static char *TEST5_BRANCH_ID = PJSIP_RFC3261_BRANCH_ID "-Test5"; 
     85static char *TEST6_BRANCH_ID = PJSIP_RFC3261_BRANCH_ID "-Test6"; 
     86static char *TEST7_BRANCH_ID = PJSIP_RFC3261_BRANCH_ID "-Test7"; 
     87static char *TEST8_BRANCH_ID = PJSIP_RFC3261_BRANCH_ID "-Test8"; 
     88static char *TEST9_BRANCH_ID = PJSIP_RFC3261_BRANCH_ID "-Test9"; 
     89 
     90#define      TEST1_ALLOWED_DIFF     (150) 
     91#define      TEST4_RETRANSMIT_CNT   3 
     92#define      TEST5_RETRANSMIT_CNT   3 
     93 
     94 
    3595static void tsx_user_on_tsx_state(pjsip_transaction *tsx, pjsip_event *e); 
    3696static pj_bool_t msg_receiver_on_rx_request(pjsip_rx_data *rdata); 
     
    52112    NULL,                               /* on_rx_request()      */ 
    53113    NULL,                               /* on_rx_response()     */ 
     114    NULL,                               /* on_tx_request()      */ 
     115    NULL,                               /* on_tx_response()     */ 
    54116    &tsx_user_on_tsx_state,             /* on_tsx_state()       */ 
    55117}; 
     
    71133    &msg_receiver_on_rx_request,        /* on_rx_request()      */ 
    72134    NULL,                               /* on_rx_response()     */ 
     135    NULL,                               /* on_tx_request()      */ 
     136    NULL,                               /* on_tx_response()     */ 
    73137    NULL,                               /* on_tsx_state()       */ 
    74138}; 
    75139 
    76 /* Static vars. */ 
     140/* Static vars, which will be reset on each test. */ 
    77141static int recv_count; 
    78142static pj_time_val recv_last; 
    79143static pj_bool_t test_complete; 
    80144 
     145/* Loop transport instance. */ 
     146static pjsip_transport *loop; 
     147 
     148/* 
     149 * This is the handler to receive state changed notification from the 
     150 * transaction. It is used to verify that the transaction behaves according 
     151 * to the test scenario. 
     152 */ 
    81153static void tsx_user_on_tsx_state(pjsip_transaction *tsx, pjsip_event *e) 
    82154{ 
    83     if (tsx->state == PJSIP_TSX_STATE_TERMINATED && test_complete==0) 
    84         test_complete = 1; 
     155    if (pj_strcmp2(&tsx->branch, TEST1_BRANCH_ID)==0) { 
     156        /* 
     157         * Transaction with TEST1_BRANCH_ID should terminate with transaction 
     158         * timeout status. 
     159         */ 
     160        if (tsx->state == PJSIP_TSX_STATE_TERMINATED) { 
     161 
     162            if (test_complete == 0) 
     163                test_complete = 1; 
     164 
     165            /* Test the status code. */ 
     166            if (tsx->status_code != PJSIP_SC_TSX_TIMEOUT) { 
     167                PJ_LOG(3,(THIS_FILE,  
     168                          "    error: status code is %d instead of %d", 
     169                          tsx->status_code, PJSIP_SC_TSX_TIMEOUT)); 
     170                test_complete = -710; 
     171            } 
     172        } 
     173 
     174    } else if (pj_strcmp2(&tsx->branch, TEST2_BRANCH_ID)==0) { 
     175        /* 
     176         * Transaction with TEST2_BRANCH_ID should terminate with transport error. 
     177         */ 
     178        if (tsx->state == PJSIP_TSX_STATE_TERMINATED) { 
     179 
     180            /* Test the status code. */ 
     181            if (tsx->status_code != PJSIP_SC_TSX_TRANSPORT_ERROR) { 
     182                PJ_LOG(3,(THIS_FILE,  
     183                          "    error: status code is %d instead of %d", 
     184                          tsx->status_code, PJSIP_SC_TSX_TRANSPORT_ERROR)); 
     185                test_complete = -720; 
     186            } 
     187 
     188            if (test_complete == 0) 
     189                test_complete = 1; 
     190        } 
     191 
     192    } else if (pj_strcmp2(&tsx->branch, TEST3_BRANCH_ID)==0) { 
     193        /* 
     194         * This test terminates the transaction while resolver is still 
     195         * running.  
     196         */ 
     197        if (tsx->state == PJSIP_TSX_STATE_CALLING) { 
     198 
     199            /* Terminate the transaction. */ 
     200            pjsip_tsx_terminate(tsx, PJSIP_SC_REQUEST_TERMINATED); 
     201 
     202        } else if (tsx->state == PJSIP_TSX_STATE_TERMINATED) { 
     203 
     204            /* Check if status code is correct. */ 
     205            if (tsx->status_code != PJSIP_SC_REQUEST_TERMINATED) { 
     206                PJ_LOG(3,(THIS_FILE,  
     207                          "    error: status code is %d instead of %d", 
     208                          tsx->status_code, PJSIP_SC_REQUEST_TERMINATED)); 
     209                test_complete = -730; 
     210            } 
     211 
     212            if (test_complete == 0) 
     213                test_complete = 1; 
     214 
     215        } 
     216 
     217    } else if (pj_strcmp2(&tsx->branch, TEST4_BRANCH_ID)==0) { 
     218        /*  
     219         * This test simulates transport failure after several  
     220         * retransmissions. 
     221         */ 
     222        if (tsx->state == PJSIP_TSX_STATE_TERMINATED) { 
     223 
     224            /* Status code must be transport error. */ 
     225            if (tsx->status_code != PJSIP_SC_TSX_TRANSPORT_ERROR) { 
     226                PJ_LOG(3,(THIS_FILE,  
     227                          "    error: status code is %d instead of %d", 
     228                          tsx->status_code, PJSIP_SC_TSX_TRANSPORT_ERROR)); 
     229                test_complete = -730; 
     230            } 
     231 
     232            /* Must have correct retransmission count. */ 
     233            if (tsx->retransmit_count != TEST4_RETRANSMIT_CNT) { 
     234                PJ_LOG(3,(THIS_FILE,  
     235                          "    error: retransmit cnt is %d instead of %d", 
     236                          tsx->retransmit_count, TEST4_RETRANSMIT_CNT)); 
     237                test_complete = -731; 
     238            } 
     239 
     240            if (test_complete == 0) 
     241                test_complete = 1; 
     242        } 
     243 
     244 
     245    } else if (pj_strcmp2(&tsx->branch, TEST5_BRANCH_ID)==0) { 
     246        /*  
     247         * This test simulates transport failure after several  
     248         * retransmissions. 
     249         */ 
     250        if (tsx->state == PJSIP_TSX_STATE_TERMINATED) { 
     251 
     252            /* Status code must be PJSIP_SC_REQUEST_TERMINATED. */ 
     253            if (tsx->status_code != PJSIP_SC_REQUEST_TERMINATED) { 
     254                PJ_LOG(3,(THIS_FILE,  
     255                          "    error: status code is %d instead of %d", 
     256                          tsx->status_code, PJSIP_SC_REQUEST_TERMINATED)); 
     257                test_complete = -733; 
     258            } 
     259 
     260            /* Must have correct retransmission count. */ 
     261            if (tsx->retransmit_count != TEST5_RETRANSMIT_CNT) { 
     262                PJ_LOG(3,(THIS_FILE,  
     263                          "    error: retransmit cnt is %d instead of %d", 
     264                          tsx->retransmit_count, TEST5_RETRANSMIT_CNT)); 
     265                test_complete = -734; 
     266            } 
     267 
     268            if (test_complete == 0) 
     269                test_complete = 1; 
     270        } 
     271 
     272 
     273    } else if (pj_strcmp2(&tsx->branch, TEST6_BRANCH_ID)==0) { 
     274        /*  
     275         * Successfull non-INVITE transaction. 
     276         */ 
     277        if (tsx->state == PJSIP_TSX_STATE_COMPLETED) { 
     278 
     279            /* Status code must be 202. */ 
     280            if (tsx->status_code != 202) { 
     281                PJ_LOG(3,(THIS_FILE,  
     282                          "    error: status code is %d instead of %d", 
     283                          tsx->status_code, 202)); 
     284                test_complete = -736; 
     285            } 
     286 
     287            /* Must have correct retransmission count. */ 
     288            if (tsx->retransmit_count != 0) { 
     289                PJ_LOG(3,(THIS_FILE,  
     290                          "    error: retransmit cnt is %d instead of %d", 
     291                          tsx->retransmit_count, 0)); 
     292                test_complete = -737; 
     293            } 
     294 
     295            /* Must still keep last_tx */ 
     296            if (tsx->last_tx == NULL) { 
     297                PJ_LOG(3,(THIS_FILE,  
     298                          "    error: transaction lost last_tx")); 
     299                test_complete = -738; 
     300            } 
     301 
     302            if (test_complete == 0) { 
     303                test_complete = 1; 
     304                pjsip_tsx_terminate(tsx, 202); 
     305            } 
     306        } 
     307    } 
    85308} 
    86309 
    87310#define DIFF(a,b)   ((a<b) ? (b-a) : (a-b)) 
    88311 
     312/* 
     313 * This is the handler to receive message for this test. It is used to 
     314 * control and verify the behavior of the message transmitted by the 
     315 * transaction. 
     316 */ 
    89317static pj_bool_t msg_receiver_on_rx_request(pjsip_rx_data *rdata) 
    90318{ 
    91     if (pj_strcmp2(&rdata->msg_info.call_id, CALL_ID1) == 0) { 
     319    if (pj_strcmp2(&rdata->msg_info.via->branch_param, TEST1_BRANCH_ID) == 0) { 
    92320        /* 
    93          * The CALL_ID1 test performs the verifications for transaction 
     321         * The TEST1_BRANCH_ID test performs the verifications for transaction 
    94322         * retransmission mechanism. It will not answer the incoming request 
    95323         * with any response. 
     
    97325        pjsip_msg *msg = rdata->msg_info.msg; 
    98326 
    99         PJ_LOG(4,("", "   received request")); 
     327        PJ_LOG(4,(THIS_FILE, "    received request")); 
    100328 
    101329        /* Only wants to take INVITE or OPTIONS method. */ 
     
    103331            msg->line.req.method.id != PJSIP_OPTIONS_METHOD) 
    104332        { 
    105             PJ_LOG(3,("", "   error: received unexpected method %.*s", 
     333            PJ_LOG(3,(THIS_FILE, "    error: received unexpected method %.*s", 
    106334                          msg->line.req.method.name.slen, 
    107335                          msg->line.req.method.name.ptr)); 
     
    112340        if (recv_count == 0) { 
    113341            recv_count++; 
    114             pj_gettimeofday(&recv_last); 
     342            //pj_gettimeofday(&recv_last); 
     343            recv_last = rdata->pkt_info.timestamp; 
    115344        } else { 
    116345            pj_time_val now; 
    117346            unsigned msec_expected, msec_elapsed; 
    118  
    119             pj_gettimeofday(&now); 
     347            int max_received; 
     348 
     349            //pj_gettimeofday(&now); 
     350            now = rdata->pkt_info.timestamp; 
    120351            PJ_TIME_VAL_SUB(now, recv_last); 
    121352            msec_elapsed = now.sec*1000 + now.msec; 
     
    127358                if (msec_expected > PJSIP_T2_TIMEOUT) 
    128359                    msec_expected = PJSIP_T2_TIMEOUT; 
    129             } 
    130  
    131             if (DIFF(msec_expected, msec_elapsed) > 100) { 
    132                 PJ_LOG(3,("","   error: expecting %d-th retransmission in %d " 
    133                              "ms, received in %d ms", 
    134                              recv_count-1, msec_expected, msec_elapsed)); 
     360                max_received = 11; 
     361            } else { 
     362                max_received = 7; 
     363            } 
     364 
     365            if (DIFF(msec_expected, msec_elapsed) > TEST1_ALLOWED_DIFF) { 
     366                PJ_LOG(3,(THIS_FILE, 
     367                          "    error: expecting retransmission no. %d in %d " 
     368                          "ms, received in %d ms", 
     369                          recv_count-1, msec_expected, msec_elapsed)); 
    135370                test_complete = -610; 
    136371            } 
    137372 
    138             if (recv_count > 7) { 
    139                 PJ_LOG(3,("", "   error: too many messages (%d) received", 
    140                               recv_count)); 
     373             
     374            if (recv_count > max_received) { 
     375                PJ_LOG(3,(THIS_FILE,  
     376                          "    error: too many messages (%d) received", 
     377                          recv_count)); 
    141378                test_complete = -620; 
    142379            } 
    143380 
    144             pj_gettimeofday(&recv_last); 
     381            //pj_gettimeofday(&recv_last); 
     382            recv_last = rdata->pkt_info.timestamp; 
    145383        } 
    146384        return PJ_TRUE; 
    147     } 
     385 
     386    } else 
     387    if (pj_strcmp2(&rdata->msg_info.via->branch_param, TEST4_BRANCH_ID) == 0) { 
     388        /* 
     389         * The TEST4_BRANCH_ID test simulates transport failure after several 
     390         * retransmissions. 
     391         */ 
     392        recv_count++; 
     393 
     394        if (recv_count == TEST4_RETRANSMIT_CNT) { 
     395            /* Simulate transport failure. */ 
     396            pjsip_loop_set_failure(loop, 2, NULL); 
     397 
     398        } else if (recv_count > TEST4_RETRANSMIT_CNT) { 
     399            PJ_LOG(3,(THIS_FILE,"   error: not expecting %d-th packet!", 
     400                      recv_count)); 
     401            test_complete = -631; 
     402        } 
     403 
     404        return PJ_TRUE; 
     405 
     406 
     407    } else 
     408    if (pj_strcmp2(&rdata->msg_info.via->branch_param, TEST5_BRANCH_ID) == 0) { 
     409        /* 
     410         * The TEST5_BRANCH_ID test simulates user terminating the transaction 
     411         * after several retransmissions. 
     412         */ 
     413        recv_count++; 
     414 
     415        if (recv_count == TEST5_RETRANSMIT_CNT+1) { 
     416            pj_str_t key; 
     417            pjsip_transaction *tsx; 
     418 
     419            pjsip_tsx_create_key( rdata->tp_info.pool, &key, PJSIP_ROLE_UAC, 
     420                                  &rdata->msg_info.msg->line.req.method, rdata); 
     421            tsx = pjsip_tsx_layer_find_tsx(&key, PJ_TRUE); 
     422            if (tsx) { 
     423                pjsip_tsx_terminate(tsx, PJSIP_SC_REQUEST_TERMINATED); 
     424                pj_mutex_unlock(tsx->mutex); 
     425            } else { 
     426                PJ_LOG(3,(THIS_FILE, "    error: uac transaction not found!")); 
     427                test_complete = -633; 
     428            } 
     429 
     430        } else if (recv_count > TEST5_RETRANSMIT_CNT+1) { 
     431            PJ_LOG(3,(THIS_FILE,"   error: not expecting %d-th packet!", 
     432                      recv_count)); 
     433            test_complete = -634; 
     434        } 
     435 
     436        return PJ_TRUE; 
     437 
     438    } else 
     439    if (pj_strcmp2(&rdata->msg_info.via->branch_param, TEST6_BRANCH_ID) == 0) { 
     440        /* 
     441         * The TEST5_BRANCH_ID test successfull non-INVITE transaction. 
     442         */ 
     443        pjsip_tx_data *tdata; 
     444        pjsip_response_addr res_addr; 
     445        pj_status_t status; 
     446 
     447        recv_count++; 
     448 
     449        if (recv_count > 1) { 
     450            PJ_LOG(3,(THIS_FILE,"   error: not expecting %d-th packet!", 
     451                      recv_count)); 
     452            test_complete = -635; 
     453        } 
     454 
     455        status = pjsip_endpt_create_response(endpt, rdata, 202, NULL, &tdata); 
     456        if (status != PJ_SUCCESS) { 
     457            app_perror("    error: unable to create response", status); 
     458            test_complete = -636; 
     459        } 
     460 
     461        status = pjsip_get_response_addr(tdata->pool, rdata, &res_addr); 
     462        if (status != PJ_SUCCESS) { 
     463            app_perror("    error: unable to get response addr", status); 
     464            test_complete = -637; 
     465        } 
     466 
     467        status = pjsip_endpt_send_response(endpt, &res_addr, tdata, NULL,NULL); 
     468        if (status != PJ_SUCCESS) { 
     469            app_perror("    error: unable to send response", status); 
     470            test_complete = -638; 
     471            pjsip_tx_data_dec_ref(tdata); 
     472        } 
     473 
     474        return PJ_TRUE; 
     475    } 
     476 
    148477    return PJ_FALSE; 
    149478} 
    150479 
    151 /***************************************************************************** 
    152  ** 
    153  ** UAC basic retransmission and timeout test. 
    154  ** 
    155  ** This will test the retransmission of the UAC transaction. Remote will not 
    156  ** answer the transaction, so the transaction should fail. The Call-ID 
    157  ** CALL_ID1 will be used for this test. 
    158  ** 
    159  ***************************************************************************** 
    160  */ 
    161 static int tsx_uac_retransmit_test(const pjsip_method *method) 
     480/*  
     481 * The generic test framework, used by most of the tests.  
     482 */ 
     483static int perform_tsx_test(int dummy, char *target_uri, char *from_uri,  
     484                            char *branch_param, int test_time,  
     485                            const pjsip_method *method) 
    162486{ 
    163487    pjsip_tx_data *tdata; 
    164488    pjsip_transaction *tsx; 
    165     char buf[80]; 
    166     pj_str_t target, from, call_id, tsx_key; 
     489    pj_str_t target, from, tsx_key; 
     490    pjsip_via_hdr *via; 
    167491    pj_time_val timeout; 
    168492    pj_status_t status; 
    169493 
    170     PJ_LOG(3,("", "  basic uac retransmission and timeout test")); 
    171  
    172     pj_sprintf(buf, "sip:alice@127.0.0.1:%d", TEST_UDP_PORT); 
    173     target = pj_str(buf); 
    174     from = pj_str("sip:bob@127.0.0.1"); 
    175     call_id = pj_str(CALL_ID1); 
     494    PJ_LOG(3,(THIS_FILE,  
     495              "   please standby, this will take at most %d seconds..", 
     496              test_time)); 
     497 
     498    /* Reset test. */ 
     499    recv_count = 0; 
     500    test_complete = 0; 
     501 
     502    /* Init headers. */ 
     503    target = pj_str(target_uri); 
     504    from = pj_str(from_uri); 
    176505 
    177506    /* Create request. */ 
    178507    status = pjsip_endpt_create_request( endpt, method, &target, 
    179                                          &from, &target, NULL, &call_id, -1,  
     508                                         &from, &target, NULL, NULL, -1,  
    180509                                         NULL, &tdata); 
    181510    if (status != PJ_SUCCESS) { 
    182511        app_perror("   Error: unable to create request", status); 
    183         return -500; 
    184     } 
     512        return -100; 
     513    } 
     514 
     515    /* Set the branch param for test 1. */ 
     516    via = pjsip_msg_find_hdr(tdata->msg, PJSIP_H_VIA, NULL); 
     517    via->branch_param = pj_str(branch_param); 
    185518 
    186519    /* Add additional reference to tdata to prevent transaction from 
     
    193526    if (status != PJ_SUCCESS) { 
    194527        app_perror("   Error: unable to create UAC transaction", status); 
    195         return -510; 
     528        pjsip_tx_data_dec_ref(tdata); 
     529        return -110; 
    196530    } 
    197531 
     
    201535    /* Send the message. */ 
    202536    status = pjsip_tsx_send_msg(tsx, NULL); 
    203     if (status != PJ_SUCCESS) { 
    204         app_perror("   Error: unable to send request", status); 
    205         return -520; 
    206     } 
     537    // Ignore send result. Some tests do deliberately triggers error 
     538    // when sending message. 
     539    //if (status != PJ_SUCCESS) { 
     540    //  app_perror("   Error: unable to send request", status); 
     541    //  pjsip_tx_data_dec_ref(tdata); 
     542    //  return -120; 
     543    //} 
     544 
    207545 
    208546    /* Set test completion time. */ 
    209547    pj_gettimeofday(&timeout); 
    210     timeout.sec += 33; 
     548    timeout.sec += test_time; 
    211549 
    212550    /* Wait until test complete. */ 
    213551    while (!test_complete) { 
    214         pj_time_val now; 
    215  
    216         pjsip_endpt_handle_events(endpt, NULL); 
     552        pj_time_val now, poll_delay = {0, 10}; 
     553 
     554        pjsip_endpt_handle_events(endpt, &poll_delay); 
    217555 
    218556        pj_gettimeofday(&now); 
    219557        if (now.sec > timeout.sec) { 
    220             PJ_LOG(3,("", "   Error: test has timed out")); 
    221             return -530; 
    222         } 
    223     } 
    224  
    225     if (status < 0) 
     558            PJ_LOG(3,(THIS_FILE, "   Error: test has timed out")); 
     559            pjsip_tx_data_dec_ref(tdata); 
     560            return -130; 
     561        } 
     562    } 
     563 
     564    if (status < 0) { 
     565        pjsip_tx_data_dec_ref(tdata); 
    226566        return status; 
     567    } 
     568 
     569    if (test_complete < 0) { 
     570        tsx = pjsip_tsx_layer_find_tsx(&tsx_key, PJ_TRUE); 
     571        if (tsx) { 
     572            pjsip_tsx_terminate(tsx, PJSIP_SC_REQUEST_TERMINATED); 
     573            pj_mutex_unlock(tsx->mutex); 
     574            flush_events(1000); 
     575        } 
     576        pjsip_tx_data_dec_ref(tdata); 
     577        return test_complete; 
     578    } 
     579 
     580    /* Allow transaction to destroy itself */ 
     581    flush_events(500); 
    227582 
    228583    /* Make sure transaction has been destroyed. */ 
    229584    if (pjsip_tsx_layer_find_tsx(&tsx_key, PJ_FALSE) != NULL) { 
    230         PJ_LOG(3,("", "   Error: transaction has not been destroyed")); 
    231         return -540; 
     585        PJ_LOG(3,(THIS_FILE, "   Error: transaction has not been destroyed")); 
     586        pjsip_tx_data_dec_ref(tdata); 
     587        return -140; 
    232588    } 
    233589 
    234590    /* Check tdata reference counter. */ 
    235591    if (pj_atomic_get(tdata->ref_cnt) != 1) { 
    236         PJ_LOG(3,("", "   Error: tdata reference counter is %d", 
     592        PJ_LOG(3,(THIS_FILE, "   Error: tdata reference counter is %d", 
    237593                      pj_atomic_get(tdata->ref_cnt))); 
    238         return -550; 
     594        pjsip_tx_data_dec_ref(tdata); 
     595        return -150; 
    239596    } 
    240597 
     
    247604/***************************************************************************** 
    248605 ** 
     606 ** TEST1_BRANCH_ID: UAC basic retransmission and timeout test. 
     607 ** 
     608 ** This will test the retransmission of the UAC transaction. Remote will not 
     609 ** answer the transaction, so the transaction should fail. The Via branch prm 
     610 ** TEST1_BRANCH_ID will be used for this test. 
     611 ** 
     612 ***************************************************************************** 
     613 */ 
     614static int tsx_uac_retransmit_test(void) 
     615{ 
     616    int status, enabled; 
     617    int i; 
     618    struct { 
     619        const pjsip_method *method; 
     620        unsigned      delay; 
     621    } sub_test[] =  
     622    { 
     623        { &pjsip_invite_method, 0}, 
     624        { &pjsip_invite_method, TEST1_ALLOWED_DIFF*2}, 
     625        { &pjsip_options_method, 0}, 
     626        { &pjsip_options_method, TEST1_ALLOWED_DIFF*2} 
     627    }; 
     628 
     629    PJ_LOG(3,(THIS_FILE, "  test1: basic uac retransmit and timeout test")); 
     630 
     631 
     632    /* For this test. message printing shound be disabled because it makes 
     633     * incorrect timing. 
     634     */ 
     635    enabled = msg_logger_set_enabled(0); 
     636 
     637    for (i=0; i<PJ_ARRAY_SIZE(sub_test); ++i) { 
     638 
     639        PJ_LOG(3,(THIS_FILE,  
     640                  "   variant %c: %s with %d ms network delay", 
     641                  ('a' + i), 
     642                  sub_test[i].method->name.ptr, 
     643                  sub_test[i].delay)); 
     644 
     645        /* Configure transport */ 
     646        pjsip_loop_set_failure(loop, 0, NULL); 
     647        pjsip_loop_set_recv_delay(loop, sub_test[i].delay, NULL); 
     648 
     649        /* Do the test. */ 
     650        status = perform_tsx_test(-500, "sip:bob@127.0.0.1;transport=loop-dgram", 
     651                                  "sip:alice@127.0.0.1;transport=loop-dgram",  
     652                                  TEST1_BRANCH_ID, 
     653                                  35, sub_test[i].method); 
     654        if (status != 0) 
     655            break; 
     656    } 
     657 
     658    /* Restore transport. */ 
     659    pjsip_loop_set_recv_delay(loop, 0, NULL); 
     660 
     661    /* Restore msg logger. */ 
     662    msg_logger_set_enabled(enabled); 
     663 
     664    /* Done. */ 
     665    return status; 
     666} 
     667 
     668/***************************************************************************** 
     669 ** 
     670 ** TEST2_BRANCH_ID: UAC resolve error test. 
     671 ** 
     672 ** Test the scenario where destination host is unresolvable. There are 
     673 ** two variants: 
     674 **  (a) resolver returns immediate error 
     675 **  (b) resolver returns error via the callback. 
     676 ** 
     677 ***************************************************************************** 
     678 */ 
     679static int tsx_resolve_error_test(void) 
     680{ 
     681    int status; 
     682 
     683    PJ_LOG(3,(THIS_FILE, "  test2: resolve error test")); 
     684 
     685    /* 
     686     * Variant (a): immediate resolve error. 
     687     */ 
     688    PJ_LOG(3,(THIS_FILE, "   variant a: immediate resolving error")); 
     689 
     690    status = perform_tsx_test(-800,  
     691                              "sip:bob@unresolved-host;transport=loop-dgram", 
     692                              "sip:alice@127.0.0.1;transport=loop-dgram",  
     693                              TEST2_BRANCH_ID, 10,  
     694                              &pjsip_options_method); 
     695    if (status != 0) 
     696        return status; 
     697 
     698    /* 
     699     * Variant (b): error via callback. 
     700     */ 
     701    PJ_LOG(3,(THIS_FILE, "   variant b: error via callback")); 
     702 
     703    /* Set loop transport to return delayed error. */ 
     704    pjsip_loop_set_failure(loop, 2, NULL); 
     705    pjsip_loop_set_send_callback_delay(loop, 10, NULL); 
     706 
     707    status = perform_tsx_test(-800, "sip:bob@127.0.0.1;transport=loop-dgram", 
     708                              "sip:alice@127.0.0.1;transport=loop-dgram",  
     709                              TEST2_BRANCH_ID, 2,  
     710                              &pjsip_options_method); 
     711    if (status != 0) 
     712        return status; 
     713 
     714    /* Restore loop transport settings. */ 
     715    pjsip_loop_set_failure(loop, 0, NULL); 
     716    pjsip_loop_set_send_callback_delay(loop, 0, NULL); 
     717 
     718    return status; 
     719} 
     720 
     721 
     722/***************************************************************************** 
     723 ** 
     724 ** TEST3_BRANCH_ID: UAC terminate while resolving test. 
     725 ** 
     726 ** Terminate the transaction while resolver is still running. 
     727 ** 
     728 ***************************************************************************** 
     729 */ 
     730static int tsx_terminate_resolving_test(void) 
     731{ 
     732    unsigned prev_delay; 
     733    pj_status_t status; 
     734 
     735    PJ_LOG(3,(THIS_FILE, "  test3: terminate while resolving test")); 
     736 
     737    /* Configure transport delay. */ 
     738    pjsip_loop_set_send_callback_delay(loop, 100, &prev_delay); 
     739 
     740    /* Start the test. */ 
     741    status = perform_tsx_test(-900, "sip:127.0.0.1;transport=loop-dgram", 
     742                              "sip:127.0.0.1;transport=loop-dgram", 
     743                              TEST3_BRANCH_ID, 2, &pjsip_options_method); 
     744 
     745    /* Restore delay. */ 
     746    pjsip_loop_set_send_callback_delay(loop, prev_delay, NULL); 
     747 
     748    return status; 
     749} 
     750 
     751 
     752/***************************************************************************** 
     753 ** 
     754 ** TEST4_BRANCH_ID: Transport failed after several retransmissions 
     755 ** 
     756 ** There are two variants of this test: (a) failure occurs immediately when 
     757 ** transaction calls pjsip_transport_send() or (b) failure is reported via 
     758 ** transport callback. 
     759 ** 
     760 ***************************************************************************** 
     761 */ 
     762static int tsx_retransmit_fail_test(void) 
     763{ 
     764    int i; 
     765    unsigned delay[] = {0, 10}; 
     766    pj_status_t status; 
     767 
     768    PJ_LOG(3,(THIS_FILE,  
     769              "  test4: transport fails after several retransmissions test")); 
     770 
     771 
     772    for (i=0; i<PJ_ARRAY_SIZE(delay); ++i) { 
     773 
     774        PJ_LOG(3,(THIS_FILE,  
     775                  "   variant %c: transport delay %d ms", ('a'+i), delay[i])); 
     776 
     777        /* Configure transport delay. */ 
     778        pjsip_loop_set_send_callback_delay(loop, delay[i], NULL); 
     779 
     780        /* Restore transport failure mode. */ 
     781        pjsip_loop_set_failure(loop, 0, 0); 
     782 
     783        /* Start the test. */ 
     784        status = perform_tsx_test(-1000, "sip:127.0.0.1;transport=loop-dgram", 
     785                                  "sip:127.0.0.1;transport=loop-dgram", 
     786                                  TEST4_BRANCH_ID, 6, &pjsip_options_method); 
     787 
     788        if (status != 0) 
     789            break; 
     790 
     791    } 
     792 
     793    /* Restore delay. */ 
     794    pjsip_loop_set_send_callback_delay(loop, 0, NULL); 
     795 
     796    /* Restore transport failure mode. */ 
     797    pjsip_loop_set_failure(loop, 0, 0); 
     798 
     799    return status; 
     800} 
     801 
     802 
     803/***************************************************************************** 
     804 ** 
     805 ** TEST5_BRANCH_ID: Terminate transaction after several retransmissions 
     806 ** 
     807 ***************************************************************************** 
     808 */ 
     809static int tsx_terminate_after_retransmit_test(void) 
     810{ 
     811    int status; 
     812 
     813    PJ_LOG(3,(THIS_FILE, "  test5: terminate after retransmissions")); 
     814 
     815    /* Do the test. */ 
     816    status = perform_tsx_test(-1100, "sip:bob@127.0.0.1;transport=loop-dgram", 
     817                              "sip:alice@127.0.0.1;transport=loop-dgram",  
     818                              TEST5_BRANCH_ID, 
     819                              6, &pjsip_options_method); 
     820 
     821    /* Done. */ 
     822    return status; 
     823} 
     824 
     825 
     826/***************************************************************************** 
     827 ** 
     828 ** TEST6_BRANCH_ID: Successfull non-invite transaction 
     829 ** 
     830 ***************************************************************************** 
     831 */ 
     832static int tsx_successfull_non_invite_test(void) 
     833{ 
     834    int i, status; 
     835    unsigned delay[] = { 1, 200 }; 
     836 
     837    PJ_LOG(3,(THIS_FILE, "  test6: successfull non-invite transaction")); 
     838 
     839    /* Do the test. */ 
     840    for (i=0; i<PJ_ARRAY_SIZE(delay); ++i) { 
     841         
     842        PJ_LOG(3,(THIS_FILE, "   variant %c: with %d ms transport delay", 
     843                             ('a'+i), delay[i])); 
     844 
     845        pjsip_loop_set_delay(loop, delay[i]); 
     846 
     847        status = perform_tsx_test(-1200,  
     848                                  "sip:bob@127.0.0.1;transport=loop-dgram", 
     849                                  "sip:alice@127.0.0.1;transport=loop-dgram", 
     850                                  TEST6_BRANCH_ID, 
     851                                  2, &pjsip_options_method); 
     852        if (status != 0) 
     853            return status; 
     854    } 
     855 
     856    pjsip_loop_set_delay(loop, 0); 
     857 
     858    /* Done. */ 
     859    return status; 
     860} 
     861 
     862 
     863/***************************************************************************** 
     864 ** 
    249865 ** UAC Transaction Test. 
    250866 ** 
     
    254870{ 
    255871    pj_sockaddr_in addr; 
    256     pj_str_t tmp; 
    257     pjsip_transport *tp; 
    258872    pj_status_t status; 
    259873 
    260     pj_sockaddr_in_init(&addr, pj_cstr(&tmp, "127.0.0.1"), TEST_UDP_PORT); 
    261  
    262     /* Start UDP transport if necessary. */ 
    263     if (pjsip_endpt_acquire_transport(endpt, PJSIP_TRANSPORT_UDP, &addr, 
    264                                       sizeof(addr), &tp) != PJ_SUCCESS) 
    265     { 
    266         addr.sin_addr.s_addr = 0; 
    267         status = pjsip_udp_transport_start( endpt, &addr, NULL, 1, NULL); 
    268         if (status != PJ_SUCCESS) { 
    269             app_perror("   Error: unable to start UDP transport", status); 
    270             return -10; 
    271         } 
    272     } else { 
    273         pjsip_transport_dec_ref(tp); 
    274     } 
    275  
    276     /* Start transaction layer module. */ 
    277     status = pjsip_tsx_layer_init(endpt); 
     874    /* Check if loop transport is configured. */ 
     875    status = pjsip_endpt_acquire_transport(endpt, PJSIP_TRANSPORT_LOOP_DGRAM,  
     876                                      &addr, sizeof(addr), &loop); 
    278877    if (status != PJ_SUCCESS) { 
    279         app_perror("   Error initializing transaction module", status); 
    280         return -20; 
     878        PJ_LOG(3,(THIS_FILE, "  Error: loop transport is not configured!")); 
     879        return -10; 
    281880    } 
    282881 
     
    290889    if (status != PJ_SUCCESS) { 
    291890        app_perror("   Error: unable to register module", status); 
    292         return -30; 
    293     } 
    294  
    295     /* Basic retransmit and timeout test for INVITE. */ 
    296     status = tsx_uac_retransmit_test(&pjsip_invite_method); 
     891        return -40; 
     892    } 
     893 
     894#if 0 
     895    /* TEST1_BRANCH_ID: Basic retransmit and timeout test. */ 
     896    status = tsx_uac_retransmit_test(); 
    297897    if (status != 0) 
    298898        return status; 
    299899 
    300     /* Basic retransmit and timeout test for non-INVITE. */ 
    301     status = tsx_uac_retransmit_test(&pjsip_options_method); 
     900    /* TEST2_BRANCH_ID: Resolve error test. */ 
     901    status = tsx_resolve_error_test(); 
    302902    if (status != 0) 
    303903        return status; 
    304904 
     905    /* TEST3_BRANCH_ID: UAC terminate while resolving test. */ 
     906    status = tsx_terminate_resolving_test(); 
     907    if (status != 0) 
     908        return status; 
     909 
     910    /* TEST4_BRANCH_ID: Transport failed after several retransmissions */ 
     911    status = tsx_retransmit_fail_test(); 
     912    if (status != 0) 
     913        return status; 
     914 
     915    /* TEST5_BRANCH_ID: Terminate transaction after several retransmissions */ 
     916    status = tsx_terminate_after_retransmit_test(); 
     917    if (status != 0) 
     918        return status; 
     919#endif 
     920 
     921    /* TEST6_BRANCH_ID: Successfull non-invite transaction */ 
     922    status = tsx_successfull_non_invite_test(); 
     923    if (status != 0) 
     924        return status; 
     925 
     926 
     927    pjsip_transport_dec_ref(loop); 
    305928    return 0; 
    306929} 
     930 
Note: See TracChangeset for help on using the changeset viewer.