通用服务器桩-Receiver使用说明文档

Galatea ·
更新时间:2024-09-21
· 931 次阅读

   通用服务器桩-Receiver使用说明文档

  1 背景

  “驱动+桩”是一种比较成熟的服务器端模块测试模式,易于实施自动化。

  Receiver应用于桩构建的场景,提高构建服务器端测试桩的效率,在大多数应用场景下用户可以通过配置xml文件实习桩功能,支持功能和性能测试使用

  Receiver只支持linux环境使用

  2 名词解释

  A模式: 普通xml解析模式

  B模式: 逻辑xml解析模式

  C模式: so加载模式

  3 功能

   ※能够模拟提供二进制socket接口的服务器程序

   ※能够支持功能与性能的要求

   ※提供三种使用模式:

  (1) 普通xml解析模式(模拟单个接口,指定接口格式及回报数据)

  (2) 逻辑xml解析模式(模拟多个接口,除指定接口格式及回报数据外,定制部分逻辑)

  (3) so加载模式(特殊场景使用,用户可以自己实现包处理函数)

  ※ 提供各类辅助函数, 帮助更快速的开发桩程序

  4 使用说明

  4.1 普通xml模式

  假设一个服务器模块提供的某个socket接口请求格式为header+req1,回包格式为header+resp1,struct描述如下:

  struct header{

  int cmd;

  char provider[200];

  int len;

  };

  struct req1{

  int id;

  };

  Struct item{

  Int a;

  Int b;

  };

  struct resp1{

  int result;

  char name[50];

  int count;

  struct item items[];

  };

  那么我们需要先构造三个xml描述

   ※header1.xml

   ※req1.xml

  ※ resp1.xml

  注:endian用来描述字节序,0为主机序(默认)

  Repeat用于指定该数据段重复数字,用于数组定义,也可以用在struct的描述上

  Type为该字段类型,工具内置类型见附录

  #flowlen()为内置函数,指定此处自动计算,根据后面所有结构体的长度计算,其他关键字见附录

  $TEMPRESULT表示从环境变量TEMPRESULT中读取数据

  @count 表示该字段值由值反填,也是5

  回包值可以指定固定值、从环境变量中读取或者利用random内置函数随机生成

  运行receiver:./receiver –p 3306 –r ./header.xml –r req1.xml –s header.xml –s resp1.xml -l 1 -u 0 -n -1 即可模拟这个服务器的接口

  那么当receiver收到一个header+req1的请求,它会回一个header+resp1的应答(result为对应系统变量实际值,name 为hello world),-l 1表示长连接, -u 0 表示tcp请求, -n -1 表示receiver不会退出,一直处理请求

  4.2 逻辑xml模式

  上个例子给出了模拟一个服务器程序单一接口的使用方法,逻辑xml主要用于模拟一个程序多个接口的场景。

  假设说某模块提供的接口格式如下:

  header1+header2+reqX

  回包格式为:

  header1+header2+respX

  (X为未知数,具体请求与回应的结构体由header2中的cmd域来定义,例如如果cmd取值为5,则请求为header1+header2+req5,回应为header1+header2+resp5)

  我们想启动一个桩实例来模拟这些接口,那么可以使用逻辑xml模式,逻辑xmll的使用方法如下:

  首先构造逻辑xml:

  [gaowei@db-testing-cs33.db01.baidu.com receiver]$ cat xml/config.xml

  运行receiver:./receiver –p 3306 –b config.xml -l 1 -u 0 -n -1 –t 5即可模拟这个服务器的多个接口

  4.3 so模式

  如果以上两种方式不能满足用户需求,用户可以继承receiver提供的plugin基类,实现自己的包处理函数

  class IPlugin

  {

  public:

  IPlugin( const std::string& name) ;

  virtual ~IPlugin();

  virtual const std::string& GetPluginName();

  virtual void Process( void *);

  protected:

  std::string m_strPluginName;

  };

  Receiver使用了Epool和线程池模型,当有socket可读,会立刻回调用户的Process( void *)函数,传给用户socket句柄,用户可自行执行收包及处理函数

  一个简单示例如下:

  testplugin.h:

  #include “plugin.h”

  class TestPlugin: public IPlugin{

  public:

  TestPlugin():IPlugin(“testplugin”){

  printf(“create TestPlugin ”);

  }

  void Process( void *);

  };

  testplugin.cpp:

  #include “testplugin.h”

  #include “mysocket.h”

  #include

  using namespace std;

  extern “C”

  TestPlugin* create_testplugin()

  {

  return new TestPlugin();

  }

  void TestPlugin::Process(void * p){

  int sock = (int)p;

  cout << ” handle epool event , socket= ” << sock << endl;

  SocketLayer::close_delepoll(sock);

  }

  5 工具参数

  receiver三种模式: xml模式(A),逻辑xml模式(B),so模式(C),参数含义如下:

    -r 指定接收的结构体描述,A模式使用

   -s 指定发送的普通结构体描述,A模式使用

   -m 指定发送的mcpack1结构体描述,A模式使用

   -x 指定发送的mcpack2结构体描述,A模式使用

   -S 指定延迟发送时间,A、B模式使用

   -n 指定响应次数(-1 表示不退出),A、B模式使用

   -l 指定处理请求后是否断连接,A、B模式使用

   -u 指定是否为udp,A、B模式使用

   -b 指定一个逻辑xml,B模式使用

   -d 指定自定义so路径,C模式使用

   -a 指定自定义so名称,C模式使用

   -t 指定线程数,A、B、C模式使用

   -p 指定端口号,A、B、C模式使用

  6 附录

  6.1 关键字列表

   #randuint(a,b):返回从a到b之间的一个随机数

   #timenow():返回当前时间的秒数

   #md5(16,str):根据str生成md5

   #fromto(a,b):返回[a,b]的整数,随运行次数递增

   #randin(a,b,c,d):在abcd中随机抽一个数

   flowlen():计算后续部分的长度

  6.2 内置类型

   int8_t uint8_t

   int16_t uint16_t

   int32_t uint32_t

   int64_t uint64_t

   int

   time_t

   long

   short

   char



说明文 服务器 通用

需要 登录 后方可回复, 如果你还没有账号请 注册新账号
相关文章
Raizel 2021-04-18
835