发现问题的应用场景
C/S结构程序,请求响应采用异步机制。即客户端发送一个请求后不是一直等待这个结果,客户端将请求存放在请求队列并获得一个JOBID,服务器运行后将运行结果存放在响应队列,客户端定时查看响应队列,根据JOBID定时从响应队列中获取结果。因此带来的测试问题是受服务器状态影响,客户端获取结果的次数不固定。
测试脚本示例
lrs_create_socket("socket0", "TCP", "LocalHost=0", "RemoteHost=localhost:8080", LrsLastArg);
lrs_send("socket0", "buf56", LrsLastArg);
lrs_receive("socket0", "buf57", LrsLastArg);
GetJobID();
do{
lr_think_time(0.3);
lrs_send("socket0", "buf58", LrsLastArg);
lrs_receive("socket0", "buf59", LrsLastArg);
}while(!CheckStatus());
其中buf56、57是发送请求,buf58、59是循环去获取结果并检查返回的标志位,若仍没有结果返回则在一定时间后循环获取结果,因此请求数不固定。
LR提示socket异常
当我用lrs_create_socket创建连接之后,当这个socket连接的请求次数达到100次后,这个连接就不可用了,必须close后再重新create。LoadRunner提示错误:Error : socket0 - Software caused connection abort. Error code : 10053.
问题验证
一开始认为是LoadRunner对Socket的支持问题,因为同样的测试方式在Rational Robot中可以通过。于是做了最简单的一个试验:
1、用socket方式录制访问某个网页并保存(如baidu、或tomcat的默认页面)
2、添加循环方式去访问
结果证明在socket请求次数达到100后即无法再次访问了(少数次数可以达到一百零几)。
脚本如下:
#include "lrs.h"
int i;
Action()
{
lr_think_time(1);
lrs_create_socket("socket0", "TCP", "LocalHost=0", "RemoteHost=appsvr01:8080", LrsLastArg);
i=1;
do{
lrs_send("socket0", "buf0", LrsLastArg);
lrs_receive("socket0", "buf1", LrsLastArg);
lr_output_message("-------------lrs request times: %d ", i);
i++;
lrs_send("socket0", "buf2", LrsLastArg);
lrs_receive("socket0", "buf3", LrsLastArg);
lr_output_message("-------------lrs request times: %d ", i);
i++;
lrs_send("socket0", "buf4", LrsLastArg);
lrs_receive("socket0", "buf5", LrsLastArg);
lr_output_message("-------------lrs request times: %d ", i);
i++;
lrs_send("socket0", "buf6", LrsLastArg);
lrs_receive("socket0", "buf7", LrsLastArg);
lr_output_message("-------------lrs request times: %d ", i);
i++;
}while(i<200);
return 0;
}
LoadRunner VUGen日志如下:
...
lrs_send(socket0, buf2)
Action.c(21): lrs_receive(socket0, buf3)
Action.c(22): -------------lrs request times: 98
Action.c(24): lrs_send(socket0, buf4)
Action.c(25): lrs_receive(socket0, buf5)
Action.c(26): -------------lrs request times: 99
Action.c(28): lrs_send(socket0, buf6)
Action.c(29): lrs_receive(socket0, buf7)
Action.c(29): Mismatch (expected 1249 bytes, 1268 bytes actually received)
Action.c(30): -------------lrs request times: 100
Action.c(16): lrs_send(socket0, buf0)
Action.c(17): lrs_receive(socket0, buf1)
Action.c(17): Error : socket0 - Software caused connection abort. Error code : 10053.
Abort was called from an action.
Ending Vuser...
Starting action vuser_end.
vuser_end.c(12): lrs_cleanup()
Ending action vuser_end.
新的发现
在发现以上问题后百思不得其解之后即和一些测试朋友进行讨论交流,但同样没有什么头绪。在一次交流中意外发现朋友的测试脚本中连接的是80端口,于是推断他是用IIS作为测试服务器,突然意识到这是否和应用服务器也有关,立即采用IIS作为服务器进行测试,居然测试通过了,并没有出现Socket连接问题!随后用Weblogic进行测试也同样通过!
初步结论
由以上的各种验证方法发现问题并非单独由LoadRunner引起的,而是和测试的应用服务器也有很大关系。仅当用LoadRunner测试Jboss、Tomcat服务器时才会出现这种问题,而对IIS、Weblogic等问题并不存在。但另有一个奇怪的问题是采用Rational Robot用同样的测试方法,所有的服务器类型都没有问题!
继续探索
后来进一步研究为何同样的采用tomcat服务器,在请求上有什么不同差异导致了两种测试工具决然不同的测试结果。但通过Charles工具只是发现了一些请求上的细微差异,并不会造成此问题的发生。于是此疑案悬而未决,希望有志之士加入一起研究,共同探索其中奥秘!