使用loadrunner進行服務器性能測試(winsocket)

由於項目進入尾聲,需要進行性能測試,沒有專業的性能測試工程師,只好自己動手,研究一下loadrunner.

發現loadrunner對web測試介紹比較多,牽涉到winsocket測試的資料極少,不過到處找一找,研究一下,也是可行的.

先說一下我們的協議,採用tcp協議,與客戶端採用自定義二進制流的方式進行通信.遵從普通的自定義協議的方式,即協議結構採用包頭+包體的形式,包頭爲固定大小的長度,並在包頭中加入包體總長度的字段.

好了,下面可以用loadrunner進行協議測試了.首先想法在PC上實現一個簡單的協議生成軟件,我採用python進行編制,將協議跑一遍,然後用loadrunner進行錄製.由於是針對單個的協議錄製,因而在loadrunner中生成的腳本一目瞭然.考慮到同一條協議根據不同的條件,返回的數據是不一樣的,因此腳本稍有點複雜.

錄製的腳本默認採用函數lrs_receive()來接收腳本,根據loadrunner的匹配規則,默認用data.ws中recv buf 中指定的長度來進行匹配,這樣,由於同一個協議返回的數據總是不斷變化的,就必然導致測試不通過的情況.在網上查到,可以通過某個設置使得每次達到錄製時的數據量即可,但這樣做有個明顯的缺陷,每次讀到到指定的數據後就不讀取了,針對短連接,或是隻測試一次的還可以,要是長連接,需要不停發送和接收的,必然出現測試不準確的問題.

以下爲解決方法,將lrs_receive改爲lrs_receive_ex,並將一次讀取改爲兩次讀取,第一次讀取固定大小的包頭,讀完包頭後,解析出包體的大小,然後再讀取包體.

此方法適用所有自定義winsocket協議,附上相關腳本.


ExpandedBlockStart.gif
複製代碼
/********************************************************************* * Created by Mercury Interactive Windows Sockets Recorder * * Created on: Fri Jul 13 16:08:19 *********************************************************************/

#include "lrs.h"


vuser_init()
{
    lrs_startup(257);


    lr_start_transaction("create_socket");
    lrs_create_socket("socket0", "TCP", "RemoteHost=127.0.0.1:110",  LrsLastArg);
    lr_end_transaction("create_socket", LR_AUTO);

    return0;
}
複製代碼
ExpandedBlockStart.gif
複製代碼
/********************************************************************* * Created by Mercury Interactive Windows Sockets Recorder * * Created on: Fri Jul 13 16:08:19 *********************************************************************/

#include "lrs.h"long getNextRecvLen(char* socketID)
{
    int NumberOfBytes = 0;
    int NextRecvLen = 0;
    char *Buffer;
    lrs_get_last_received_buffer(socketID, &Buffer, &NumberOfBytes);
    memcpy((char*)&NextRecvLen, Buffer+20, 4); 
    lr_log_message("last_received:%d, NextRecvLen:%d", NumberOfBytes, NextRecvLen);
    return NextRecvLen;
}

int receive_ex(char* socketID, char* buf)
{
    long NextRecvLen = getNextRecvLen(socketID);//getNextRecvLen("socket0");char flag[50];
    memset(flag, 0, sizeof(flag));
    sprintf(flag, "NumberOfBytesToRecv=%d", NextRecvLen);  
    lr_log_message(flag); 
    lrs_receive_ex(socketID, buf, flag, LrsLastArg);

}

void doOneThing(int index)
{

     char sendbuf[50];
     char recvbuf1[50];
     char recvbuf2[50];
     char transbuf[50];

     memset(transbuf, 0, sizeof(transbuf));
     sprintf(transbuf, "one_send_recv_%d", index);

     lr_start_transaction(transbuf);
    
         memset(sendbuf, 0, sizeof(sendbuf));
         memset(recvbuf1, 0, sizeof(recvbuf1));
         memset(recvbuf2, 0, sizeof(recvbuf2));
         sprintf(sendbuf, "buf%d", 2*index);
         sprintf(recvbuf1, "buf%d", 2*index+1);
         sprintf(recvbuf2, "dbuf%d", index);

         lrs_send("socket0", sendbuf, LrsLastArg);
         lrs_receive_ex("socket0", recvbuf1, "NumberOfBytesToRecv=32", LrsLastArg);
         receive_ex("socket0", recvbuf2);
    
     lr_end_transaction(transbuf, LR_AUTO);

 

}

Action()
{

    lr_rendezvous("read_all_req_0");
    doOneThing(0);
}
複製代碼
ExpandedBlockStart.gif
複製代碼
/********************************************************************* * Created by Mercury Interactive Windows Sockets Recorder * * Created on: Fri Jul 13 16:08:19 *********************************************************************/

#include "lrs.h"


vuser_end()
{

    lrs_close_socket("socket0");
    lrs_cleanup();

    return0;
}
複製代碼

由於是分兩次讀取數據,必然讀取的內容與錄製的會稍有不同,幸好我們判斷成功與否不是用返回的數據進行比較,而只是覈對一下數據的大小,因此完全可以手動修改數據腳本,以下爲在錄製的基礎上手工修改的腳本(注意,只是更改了接收端)

send  buf0 28
"Test"
"\x00\x1b\x00\x00\x00"
"\x00\x00\x00\x00"
"\x12\x01\x00\x00\x00\x01\x00\x00\x00"
"\x02\x00\x01\x00\x01\x00"

recv  buf1 -1

recv rbuf0 -1



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章