gitee.com/KyleChenSource/lib-robot@v1.0.2/robottest/testcaseimp/brutetest.go (about)

     1  package testcaseimp
     2  
     3  /*
     4  	暴力测试
     5  	配置 [
     6  		// 根据循序进行测试
     7  			{
     8  			'name': // 协议名
     9  			'id': // 协议id, 可以为0
    10  			'notest':
    11  			'data': { //发送的协议
    12  				%INT8%  16,32,64:[min:max:...valid value]
    13  				%RAND_UINT8%  16,32,64:[min:max:...valid value]
    14  				%RAND_FLOAT32%  64:[min:max:...valid value]
    15  				%RAND_BOOL%
    16  				%RAND_STRING% :[min:max:...valid value]
    17  				%RAND_BYTES[m:n]% :[min:max:...valid value]
    18  				%RAND_MSG:msgName%
    19  				%RAND_ARRAY:msgName[minLen:maxLen]% :[min:max:...valid value]
    20  			}
    21  		]
    22  	}
    23  */
    24  import (
    25  	"fmt"
    26  	"time"
    27  
    28  	"gitee.com/KyleChenSource/lib-robot/robottest/common"
    29  	"gitee.com/KyleChenSource/lib-robot/robottest/common/brutetest"
    30  	"gitee.com/KyleChenSource/lib-robot/robottest/robot/statistic"
    31  	"gitee.com/KyleChenSource/lib-robot/robottest/robot/testcase"
    32  
    33  	"gitee.com/KyleChenSource/lib-robot/robottest/protos"
    34  
    35  	"gitee.com/KyleChenSource/lib-robot/robottest/log"
    36  )
    37  
    38  const (
    39  	prePath = "./brutetest"
    40  )
    41  
    42  type BruteTestFactory struct {
    43  }
    44  
    45  type BruteTestCnf struct {
    46  	testcase.TestcaseActionConfig_
    47  	Cid   int
    48  	Index int
    49  }
    50  
    51  func (this *BruteTestFactory) Cnf() testcase.TestcaseActionCnf {
    52  	return &BruteTestCnf{}
    53  }
    54  
    55  func (this *BruteTestFactory) New(id testcase.TestActionID, tf testcase.ITestFlow, cnf testcase.TestcaseActionCnf) (testcase.ITestcaseAction, error) {
    56  	bruteCnf := cnf.(*BruteTestCnf)
    57  	name := fmt.Sprintf("brute_%d_%d", bruteCnf.Cid, bruteCnf.Index)
    58  	b, ok := tf.TestCtx().Get(name)
    59  	if ok {
    60  		brute := b.(*BruteTest)
    61  		brute._id = id
    62  		brute._tf = tf
    63  
    64  		return b.(*BruteTest), nil
    65  	}
    66  
    67  	n := &BruteTest{
    68  		_id:  id,
    69  		_tf:  tf,
    70  		_cnf: cnf.(*BruteTestCnf),
    71  	}
    72  	tf.TestCtx().Set(name, n)
    73  	return n, nil
    74  }
    75  
    76  func init() {
    77  	testcase.TESTCASEACTION_MGR.Register("BruteTest", &BruteTestFactory{})
    78  }
    79  
    80  type BruteTest struct {
    81  	_id       testcase.TestActionID
    82  	_tf       testcase.ITestFlow
    83  	_cnf      *BruteTestCnf
    84  	_gen      *brutetest.BruteMsgGenerator
    85  	_index    int // 当前协议的次数记录
    86  	_data     protos.JsonString
    87  	_timeSend int64 // 发送时间
    88  	_timer    *common.TimeInterface
    89  }
    90  
    91  // 启动
    92  // 目前仅仅支持定时器和消息两种驱动模式
    93  func (this *BruteTest) Start() error {
    94  	if this._gen == nil {
    95  		cnf := brutetest.BrutetestCaselistMap[this._cnf.Cid][this._cnf.Index]
    96  		this._gen = cnf.Generator(0, 0)
    97  		if this._gen == nil {
    98  			return fmt.Errorf("%s %s Generator nil", this._tf.LogPre(), cnf.MsgName)
    99  		}
   100  
   101  		log.LogInfo("%s %s Generator. Count:%d",
   102  			this._tf.LogPre(),
   103  			cnf.MsgName,
   104  			this._gen.Count())
   105  	} else {
   106  		log.LogInfo("%s %s Generator. Count:%d index:%d",
   107  			this._tf.LogPre(),
   108  			this._gen.BruteCnf().MsgName,
   109  			this._gen.Count(),
   110  			this._index)
   111  	}
   112  
   113  	// 初始化配置
   114  	this.msgSend()
   115  	return nil
   116  }
   117  
   118  // 停止,需要删除目前所有的驱动注册
   119  func (this *BruteTest) Stop() {
   120  	if this._timer != nil {
   121  		this._tf.TestCtx().TimerDel(this._timer)
   122  		this._timer = nil
   123  	}
   124  }
   125  
   126  func (this *BruteTest) ID() testcase.TestActionID {
   127  	return this._id
   128  }
   129  
   130  func (this *BruteTest) Name() string {
   131  	return this._cnf.ActionName()
   132  }
   133  
   134  func (this *BruteTest) Testflow() testcase.ITestFlow {
   135  	return this._tf
   136  }
   137  
   138  func (this *BruteTest) OnMsg(protoId protos.ProtoID, header protos.JsonString, data protos.JsonString) {
   139  	tCost := time.Now().UnixMilli() - this._timeSend
   140  	log.LogInfo("MsgResponse OK. %s action:%d OnMsg:%d index:%d header:%s data:%s timeCost:%d",
   141  		this._tf.LogPre(),
   142  		this._id,
   143  		protoId,
   144  		this._index-1,
   145  		header, data, tCost)
   146  
   147  	if this._timer != nil {
   148  		this._tf.TestCtx().TimerDel(this._timer)
   149  		this._timer = nil
   150  	}
   151  
   152  	this._tf.TestCtx().MsgHandleUnreg(protos.ProtoID(this._gen.BruteCnf().ResponeId), this)
   153  	statistic.Record(&statistic.StatisticEvent{
   154  		Type: statistic.StatisticType_Msg_Success,
   155  		ID:   int(protoId),
   156  		Time: tCost,
   157  	})
   158  
   159  	this.msgSend()
   160  }
   161  
   162  func (this *BruteTest) msgSend() {
   163  	ok, data := this._gen.Next()
   164  	if !ok {
   165  		this._tf.OnActionEnd(this, nil, this._cnf.FailContinue)
   166  		return
   167  	}
   168  
   169  	this._data = protos.JsonString(data)
   170  	err := this._tf.TestCtx().Send(protos.ProtoID(this._gen.BruteCnf().MsgId), this._data)
   171  	if err != nil {
   172  		this._tf.OnActionEnd(this, fmt.Errorf("SendMsg %d(%s) err:%s",
   173  			this._gen.BruteCnf().MsgId,
   174  			this._gen.BruteCnf().MsgName,
   175  			err.Error()),
   176  			this._cnf.FailContinue)
   177  		return
   178  	}
   179  
   180  	log.LogInfo("%s action:%d msgSend:%d(%s) index:%d data:%s", this._tf.LogPre(), this._id,
   181  		this._gen.BruteCnf().MsgId,
   182  		this._gen.BruteCnf().MsgName,
   183  		this._index,
   184  		data,
   185  	)
   186  	this._index++
   187  
   188  	this._timeSend = time.Now().UnixMilli()
   189  	// 发送成功,开始等待需要的回包
   190  	if this._gen.BruteCnf().ResponeId != 0 {
   191  		this._tf.TestCtx().MsgHandleReg(protos.ProtoID(this._gen.BruteCnf().ResponeId), this)
   192  
   193  		if this._gen.BruteCnf().Timeout != 0 {
   194  			this._timer, err = this._tf.TestCtx().TimerAdd(this._gen.BruteCnf().Timeout,
   195  				this.OnTimerResponseTimeout,
   196  				nil)
   197  		}
   198  	} else if this._gen.BruteCnf().Timeout != 0 {
   199  		statistic.Record(&statistic.StatisticEvent{
   200  			Type: statistic.StatisticType_Msg_Success,
   201  			ID:   int(this._gen.BruteCnf().MsgId),
   202  			Time: 0,
   203  		})
   204  		this._timer, err = this._tf.TestCtx().TimerAdd(this._gen.BruteCnf().Timeout,
   205  			this.OnTimerNext,
   206  			nil)
   207  	} else {
   208  		statistic.Record(&statistic.StatisticEvent{
   209  			Type: statistic.StatisticType_Msg_Success,
   210  			ID:   int(this._gen.BruteCnf().MsgId),
   211  			Time: 0,
   212  		})
   213  		this._timer, err = this._tf.TestCtx().TimerAdd(10,
   214  			this.OnTimerNext,
   215  			nil)
   216  	}
   217  }
   218  
   219  func (this *BruteTest) OnTimerNext(t *common.TimeInterface, data any) int64 {
   220  	this._timer = nil
   221  
   222  	this.msgSend()
   223  	return 0
   224  }
   225  
   226  func (this *BruteTest) OnTimerResponseTimeout(t *common.TimeInterface, data any) int64 {
   227  	this._timer = nil
   228  	log.LogInfo("MsgResponse Timeout. %s action:%d OnMsg:%d index:%d timeOut:%d data:%s",
   229  		this._tf.LogPre(),
   230  		this._id,
   231  		this._gen.BruteCnf().ResponeId,
   232  		this._index-1,
   233  		this._gen.BruteCnf().Timeout,
   234  		this._data)
   235  
   236  	statistic.Record(&statistic.StatisticEvent{
   237  		Type: statistic.StatisticType_Msg_Timeout,
   238  		ID:   int(this._gen.BruteCnf().ResponeId),
   239  	})
   240  
   241  	this.msgSend()
   242  	return 0
   243  }