gitee.com/KyleChenSource/lib-robot@v1.0.2/robottest/testcaseimp/brutetest_task.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 ctx_register_key = "action_brutetesttask" 40 ) 41 42 type BruteTestTaskFactory struct { 43 } 44 45 type BruteTestTaskCnf struct { 46 testcase.TestcaseActionConfig_ 47 } 48 49 func (this *BruteTestTaskFactory) Cnf() testcase.TestcaseActionCnf { 50 return &BruteTestTaskCnf{} 51 } 52 53 func (this *BruteTestTaskFactory) New(id testcase.TestActionID, tf testcase.ITestFlow, cnf testcase.TestcaseActionCnf) (testcase.ITestcaseAction, error) { 54 b, ok := tf.TestCtx().Get(ctx_register_key) 55 if ok { 56 brute := b.(*BruteTestTask) 57 brute._id = id 58 brute._tf = tf 59 60 return b.(*BruteTestTask), nil 61 } 62 63 n := &BruteTestTask{ 64 _id: id, 65 _tf: tf, 66 _cnf: cnf.(*BruteTestTaskCnf), 67 } 68 tf.TestCtx().Set(ctx_register_key, n) 69 return n, nil 70 } 71 72 func init() { 73 testcase.TESTCASEACTION_MGR.Register("BruteTestTask", &BruteTestTaskFactory{}) 74 } 75 76 type BruteTestTask struct { 77 _id testcase.TestActionID 78 _tf testcase.ITestFlow 79 _cnf *BruteTestTaskCnf 80 81 _task *brutetest.BrutetestTask 82 83 _brutemsgcnf []*brutetest.BruteMsgCnf 84 _gen *brutetest.BruteMsgGenerator 85 _index int // 当前测试流的索引id 86 _logname string 87 _cnt int // 当前测试流的索引id 88 _data protos.JsonString 89 _timeSend int64 // 发送时间 90 _timer *common.TimeInterface 91 } 92 93 func (this *BruteTestTask) taskGet() bool { 94 task, ok := <-brutetest.BrutetestTaskChan 95 if !ok { 96 // 通道关闭,结束 97 return false 98 } 99 100 this._brutemsgcnf, _ = brutetest.BrutetestCaselistMap[task.Cid] 101 this._index = len(this._brutemsgcnf) - 1 102 this._task = task 103 104 this.genGet() 105 106 log.LogInfo("%s %s BruteTestTask gen:%d cid:%d skip:%d limit:%d", 107 this._tf.LogPre(), 108 this._logname, 109 len(this._brutemsgcnf), 110 task.Cid, 111 task.Skip, 112 task.Limit) 113 114 return true 115 } 116 117 func (this *BruteTestTask) genGet() { 118 if this._index == 0 { 119 this._gen = this._brutemsgcnf[this._index].Generator(this._task.Skip, this._task.Limit) 120 this._logname = fmt.Sprintf("%s_%s_fin_%d(%d)", this._cnf.Name, this._brutemsgcnf[this._index].MsgName, this._task.Skip, this._task.Limit) 121 } else { 122 this._gen = this._brutemsgcnf[this._index].Generator(0, 0) 123 this._logname = fmt.Sprintf("%s_%s_mid_%d(%d)", this._cnf.Name, this._brutemsgcnf[this._index].MsgName, len(this._brutemsgcnf)-this._index-1, len(this._brutemsgcnf)) 124 } 125 126 log.LogInfo("%s %s BruteTestTask gen:%d msgsendCnt:%d", 127 this._tf.LogPre(), 128 this._logname, 129 len(this._brutemsgcnf), 130 this._cnt) 131 } 132 133 // 启动 134 // 目前仅仅支持定时器和消息两种驱动模式 135 func (this *BruteTestTask) Start() error { 136 if this._task == nil { 137 ok := this.taskGet() 138 if !ok { 139 // 通道关闭,结束 140 this._tf.OnActionEnd(this, nil, this._cnf.FailContinue) 141 return nil 142 } 143 } else if len(this._brutemsgcnf) > 1 { 144 this._index = len(this._brutemsgcnf) - 1 145 this.genGet() 146 } 147 148 // 初始化配置 149 this.msgSend() 150 return nil 151 } 152 153 // 停止,需要删除目前所有的驱动注册 154 func (this *BruteTestTask) Stop() { 155 if this._timer != nil { 156 this._tf.TestCtx().TimerDel(this._timer) 157 this._timer = nil 158 } 159 } 160 161 func (this *BruteTestTask) ID() testcase.TestActionID { 162 return this._id 163 } 164 165 func (this *BruteTestTask) Name() string { 166 return this._logname 167 } 168 169 func (this *BruteTestTask) Testflow() testcase.ITestFlow { 170 return this._tf 171 } 172 173 func (this *BruteTestTask) OnMsg(protoId protos.ProtoID, header protos.JsonString, data protos.JsonString) { 174 tCost := time.Now().UnixMilli() - this._timeSend 175 log.LogInfo("MsgResponse OK. %s action:%s OnMsg:%d index:%d header:%s data:%s timeCost:%d", 176 this._tf.LogPre(), 177 this._logname, 178 protoId, 179 this._cnt-1, 180 header, data, tCost) 181 182 if this._timer != nil { 183 this._tf.TestCtx().TimerDel(this._timer) 184 this._timer = nil 185 } 186 187 this._tf.TestCtx().MsgHandleUnreg(protos.ProtoID(this._gen.BruteCnf().ResponeId), this) 188 statistic.Record(&statistic.StatisticEvent{ 189 Type: statistic.StatisticType_Msg_Success, 190 ID: int(protoId), 191 Time: tCost, 192 }) 193 194 this.msgSend() 195 } 196 197 func (this *BruteTestTask) msgSend() { 198 ok, data := this._gen.Next() 199 if !ok { 200 this._index-- 201 if this._index < 0 { 202 // 结束了 203 ok = this.taskGet() 204 if !ok { 205 this._tf.OnActionEnd(this, nil, this._cnf.FailContinue) 206 return 207 } 208 } else { 209 this.genGet() 210 } 211 212 if this._gen == nil { 213 this._tf.OnActionEnd(this, fmt.Errorf("BruteTestTask len:%d cid:%d skip:%d limit:%d index:%d gen nil", 214 len(this._brutemsgcnf), 215 this._task.Cid, 216 this._task.Skip, 217 this._task.Limit, 218 this._index), this._cnf.FailContinue) 219 return 220 } 221 222 ok, data = this._gen.Next() 223 if !ok { 224 this._tf.OnActionEnd(this, fmt.Errorf("BruteTestTask len:%d cid:%d skip:%d limit:%d index:%d gen first nil", 225 len(this._brutemsgcnf), 226 this._task.Cid, 227 this._task.Skip, 228 this._task.Limit, 229 this._index), this._cnf.FailContinue) 230 return 231 } 232 } 233 234 this._data = protos.JsonString(data) 235 err := this._tf.TestCtx().Send(protos.ProtoID(this._gen.BruteCnf().MsgId), this._data) 236 if err != nil { 237 this._tf.OnActionEnd(this, fmt.Errorf("SendMsg %d(%s) err:%s", 238 this._gen.BruteCnf().MsgId, 239 this._gen.BruteCnf().MsgName, 240 err.Error()), 241 this._cnf.FailContinue) 242 return 243 } 244 245 log.LogInfo("%s action:%s msgSend:%d(%s) index:%d left:%d data:%s", 246 this._tf.LogPre(), 247 this._logname, 248 this._gen.BruteCnf().MsgId, 249 this._gen.BruteCnf().MsgName, 250 this._cnt, 251 this._task.Limit, 252 data, 253 ) 254 this._cnt++ 255 256 this._timeSend = time.Now().UnixMilli() 257 // 发送成功,开始等待需要的回包 258 if this._gen.BruteCnf().ResponeId != 0 { 259 this._tf.TestCtx().MsgHandleReg(protos.ProtoID(this._gen.BruteCnf().ResponeId), this) 260 261 if this._gen.BruteCnf().Timeout != 0 { 262 this._timer, err = this._tf.TestCtx().TimerAdd(this._gen.BruteCnf().Timeout, 263 this.OnTimerResponseTimeout, 264 nil) 265 } 266 } else if this._gen.BruteCnf().Timeout != 0 { 267 statistic.Record(&statistic.StatisticEvent{ 268 Type: statistic.StatisticType_Msg_Success, 269 ID: int(this._gen.BruteCnf().MsgId), 270 Time: 0, 271 }) 272 this._timer, err = this._tf.TestCtx().TimerAdd(this._gen.BruteCnf().Timeout, 273 this.OnTimerNext, 274 nil) 275 } else { 276 statistic.Record(&statistic.StatisticEvent{ 277 Type: statistic.StatisticType_Msg_Success, 278 ID: int(this._gen.BruteCnf().MsgId), 279 Time: 0, 280 }) 281 this._timer, err = this._tf.TestCtx().TimerAdd(10, 282 this.OnTimerNext, 283 nil) 284 } 285 } 286 287 func (this *BruteTestTask) OnTimerNext(t *common.TimeInterface, data any) int64 { 288 this._timer = nil 289 290 this.msgSend() 291 return 0 292 } 293 294 func (this *BruteTestTask) OnTimerResponseTimeout(t *common.TimeInterface, data any) int64 { 295 this._timer = nil 296 log.LogInfo("MsgResponse Timeout. %s action:%s OnMsg:%d index:%d timeOut:%d data:%s", 297 this._tf.LogPre(), 298 this._logname, 299 this._gen.BruteCnf().ResponeId, 300 this._cnt-1, 301 this._gen.BruteCnf().Timeout, 302 this._data) 303 304 statistic.Record(&statistic.StatisticEvent{ 305 Type: statistic.StatisticType_Msg_Timeout, 306 ID: int(this._gen.BruteCnf().ResponeId), 307 }) 308 309 this.msgSend() 310 return 0 311 }