gitee.com/KyleChenSource/lib-robot@v1.0.2/robottest/robot/robot_manager.go (about) 1 package robot 2 3 import ( 4 "fmt" 5 "os" 6 7 "gitee.com/KyleChenSource/lib-robot/robottest/common" 8 "gitee.com/KyleChenSource/lib-robot/robottest/common/brutetest" 9 "gitee.com/KyleChenSource/lib-robot/robottest/log" 10 "gitee.com/KyleChenSource/lib-robot/robottest/protos" 11 "gitee.com/KyleChenSource/lib-robot/robottest/robot/net" 12 "gitee.com/KyleChenSource/lib-robot/robottest/robot/statistic" 13 "gitee.com/KyleChenSource/lib-robot/robottest/robot/testcase" 14 "gitee.com/KyleChenSource/lib-robot/robottest/testcaseimp" 15 ) 16 17 type co_bot_end_msg struct { 18 _err error 19 _robot *Robot 20 } 21 type RobotManager struct { 22 Msglen_get net.MsgLenGet 23 Msgmin_get net.MsgMinGet 24 Msg_decode net.MsgDecode 25 Msg_encode net.MsgEncode 26 Msg_decode_protoid net.MsgDecodeProtoID 27 28 _count int 29 _robots []*Robot 30 _chan_bot_quit chan co_bot_end_msg 31 32 _statistics_cnt_success int // 成功结束robots 33 _statistics_cnt_failed int // 失败结束robots 34 35 _signal chan os.Signal 36 } 37 38 func (this *RobotManager) robotAdd(r *Robot) { 39 this._robots = append(this._robots, r) 40 this._count++ 41 statistic.Record(&statistic.StatisticEvent{ 42 Type: statistic.StatisticType_Robot_Create, 43 Name: r._cnfName, 44 }) 45 } 46 47 func (this *RobotManager) InitializeBrutetest() error { 48 // 进行暴力协议测试 49 log.LogInfo("RobotManager Brutetest %s", TEST_CNF.Brute.File) 50 err := brutetest.BruteTestCreate(TEST_CNF.Brute.File) 51 if err != nil { 52 return err 53 } 54 55 for cid, cnfs := range brutetest.BrutetestCaselistMap { 56 caseName := fmt.Sprintf("brute_%d", cid) 57 robotCnf := RobotConfig{ 58 Relogin: true, 59 Case_Login: TEST_CNF.Brute.Login, 60 Case_Relogin: TEST_CNF.Brute.Relogin, 61 Cases: make([]*TestCaseRunnerConfig, 1), 62 } 63 robotCnf.Cases[0] = &TestCaseRunnerConfig{ 64 Do: caseName, 65 Count: 0, 66 } 67 68 testcaseCnf := &testcase.TestcaseConfig{ 69 Name: caseName, 70 TestFlow: make([][]testcase.TestcaseActionCnf, 1), 71 } 72 testcaseCnf.TestFlow[0] = make([]testcase.TestcaseActionCnf, len(cnfs)) 73 for j := 0; j < len(cnfs); j++ { 74 actionCnf := &testcaseimp.BruteTestCnf{ 75 Cid: cid, 76 Index: len(cnfs) - j - 1, 77 } 78 actionCnf.Name = "BruteTest" 79 testcaseCnf.TestFlow[0][j] = actionCnf 80 } 81 82 TESTCASE_CNF[caseName] = testcaseCnf 83 84 accountName := fmt.Sprintf("%s%d", TEST_CNF.AccountPre, this._count+int(TEST_CNF.AccountOffset)) 85 robotv := Robot{} 86 err := robotv.InitializeCnf(this._count, this, TEST_CNF.Server, accountName, &robotCnf, true, nil, nil) 87 if err != nil { 88 log.LogInfo("RobotManager Initialize robot:%s failed", accountName) 89 continue 90 } 91 92 this.robotAdd(&robotv) 93 } 94 95 return nil 96 } 97 98 func (this *RobotManager) InitializeBrutetestTask() error { 99 // 进行暴力协议测试 100 log.LogInfo("RobotManager BrutetestTask %s", TEST_CNF.Brute.File) 101 taskCnt, err := brutetest.BrutetestTaskCreate(TEST_CNF.Brute.File) 102 if err != nil { 103 return err 104 } 105 106 robotCnt := taskCnt 107 if robotCnt > TEST_CNF.Brute.RobotCnt { 108 robotCnt = TEST_CNF.Brute.RobotCnt 109 } 110 111 // 创建case配置 112 caseName := "brutetesttask" 113 testcaseCnf := &testcase.TestcaseConfig{ 114 Name: caseName, 115 TestFlow: make([][]testcase.TestcaseActionCnf, 1), 116 } 117 testcaseCnf.TestFlow[0] = make([]testcase.TestcaseActionCnf, 1) 118 actionCnf := &testcaseimp.BruteTestTaskCnf{} 119 actionCnf.Name = "BruteTestTask" 120 testcaseCnf.TestFlow[0][0] = actionCnf 121 TESTCASE_CNF[fmt.Sprintf("%s/%s", "", caseName)] = testcaseCnf 122 123 // 创建机器人 124 for i := 0; i < robotCnt; i++ { 125 robotCnf := RobotConfig{ 126 Relogin: true, 127 File_Login: TEST_CNF.Brute.File_Login, 128 Case_Login: TEST_CNF.Brute.Login, 129 Case_Relogin: TEST_CNF.Brute.Relogin, 130 Cases: make([]*TestCaseRunnerConfig, 1), 131 } 132 133 robotCnf.Cases[0] = &TestCaseRunnerConfig{ 134 Do: caseName, 135 Count: 0, 136 } 137 138 accountName := fmt.Sprintf("%s%d", TEST_CNF.AccountPre, this._count+int(TEST_CNF.AccountOffset)) 139 robotv := Robot{} 140 err := robotv.InitializeCnf(this._count, this, TEST_CNF.Server, accountName, &robotCnf, true, nil, nil) 141 if err != nil { 142 log.LogInfo("RobotManager Initialize robot:%s failed", accountName) 143 continue 144 } 145 146 robotCnf.Name = fmt.Sprintf("brute_%d(%d)", i, robotCnt) 147 this.robotAdd(&robotv) 148 } 149 150 log.LogInfo("RobotManager BrutetestTask taskcnt:%d robotcnt:%d", taskCnt, robotCnt) 151 return nil 152 } 153 154 func (this *RobotManager) Initialize(func_msglen_get net.MsgLenGet, 155 func_msgmin_get net.MsgMinGet, 156 func_msg_decodeprotoid net.MsgDecodeProtoID, 157 func_msg_decode net.MsgDecode, 158 func_msg_encode net.MsgEncode, 159 func_msg_gen protos.MsgGenerate) error { 160 this.Msglen_get = func_msglen_get 161 this.Msgmin_get = func_msgmin_get 162 this.Msg_decode = func_msg_decode 163 this.Msg_encode = func_msg_encode 164 this.Msg_decode_protoid = func_msg_decodeprotoid 165 protos.ProtoGeneratorInit(func_msg_gen) 166 167 this._count = 0 168 this._chan_bot_quit = make(chan co_bot_end_msg, 10) 169 170 this._signal = make(chan os.Signal) 171 Signal(this._signal) 172 173 if TEST_CNF.Statistic.StatisticTickInterval > 0 || TEST_CNF.Statistic.StatisticTotTime > 0 { 174 log.LogInfo("Statistic Start") 175 statistic.Start(TEST_CNF.Statistic.StatisticTickInterval, 176 TEST_CNF.Statistic.StatisticTotTime, 177 TEST_CNF.Statistic.ActionTimeOver) 178 } 179 180 log.LogInfo("RobotManager Initialize Start") 181 if TEST_CNF.Brute != nil { 182 err := this.InitializeBrutetestTask() 183 if err != nil { 184 return err 185 } 186 } 187 for i := 0; i < len(TEST_CNF.Robots); i++ { 188 log.LogInfo("RobotManager Initialize robot:%s count:%d offset:%d", TEST_CNF.Robots[i].Robot, TEST_CNF.Robots[i].Count, this._count) 189 var ignores map[protos.ProtoID]bool 190 focus := make(map[protos.ProtoID]bool) 191 for _, protoid := range TEST_CNF.Robots[i].Focus { 192 log.LogDebug("Focus:%d", protoid) 193 focus[protos.ProtoID(protoid)] = true 194 } 195 196 if len(focus) == 0 { 197 ignores = make(map[protos.ProtoID]bool) 198 for _, protoid := range TEST_CNF.Robots[i].Ignores { 199 log.LogDebug("ignore:%d", protoid) 200 ignores[protos.ProtoID(protoid)] = true 201 } 202 } 203 204 for j := 0; j < TEST_CNF.Robots[i].Count; j++ { 205 robotv := Robot{} 206 accountName := fmt.Sprintf("%s%d", TEST_CNF.AccountPre, this._count+int(TEST_CNF.AccountOffset)) 207 err := robotv.Initialize(this._count, this, TEST_CNF.Server, accountName, TEST_CNF.Robots[i].File, TEST_CNF.Robots[i].Robot, TEST_CNF.Robots[i].Monitor, ignores, focus) 208 if err != nil { 209 log.LogInfo("RobotManager robot:%s intiailize err:%s", accountName, err.Error()) 210 continue 211 } 212 213 this.robotAdd(&robotv) 214 } 215 } 216 217 return nil 218 } 219 220 func (this *RobotManager) Run() { 221 defer func() { 222 log.LogInfo("RobotManager Fin success_cnt:%d failed_cnt:%d", this._statistics_cnt_success, this._statistics_cnt_failed) 223 statistic.Stop() 224 }() 225 defer common.PanicLog(nil) 226 227 for _, bot := range this._robots { 228 err := bot.Start() 229 if err != nil { 230 this._count-- 231 log.LogError("RobotManager robot:%s Start err:%s. robot_cnt:%d", bot.Name(), err.Error(), this._count) 232 } 233 } 234 235 for this._count > 0 { 236 select { 237 case msg := (<-this._chan_bot_quit): 238 this._count-- 239 if msg._err == nil { 240 this._statistics_cnt_success++ 241 log.LogInfo("RobotManager robot:%s (%s) end success. robot_cnt left:%d success_cnt:%d failed_cnt:%d costTime:%d", msg._robot.Name(), msg._robot.CnfName(), this._count, this._statistics_cnt_success, this._statistics_cnt_failed, msg._robot._statistics_time_end-msg._robot._statistics_time_start) 242 } else { 243 this._statistics_cnt_failed++ 244 log.LogError("RobotManager robot:%s (%s) end err:%s. robot_cnt left:%d success_cnt:%d failed_cnt:%d", msg._robot.Name(), msg._robot.CnfName(), msg._err.Error(), this._count, this._statistics_cnt_success, this._statistics_cnt_failed) 245 } 246 case <-this._signal: 247 for _, bot := range this._robots { 248 bot.kill() 249 } 250 } 251 } 252 } 253 254 func (this *RobotManager) RobotFinCallback(bot *Robot, err error) { 255 msg := co_bot_end_msg{} 256 msg._err = err 257 msg._robot = bot 258 259 if err == nil { 260 statistic.Record(&statistic.StatisticEvent{ 261 Type: statistic.StatisticType_Robot_Success, 262 Name: bot._cnfName, 263 }) 264 } else if err.Error() == "Close from signal" { 265 statistic.Record(&statistic.StatisticEvent{ 266 Type: statistic.StatisticType_Robot_Close, 267 Name: bot._cnfName, 268 }) 269 } else { 270 statistic.Record(&statistic.StatisticEvent{ 271 Type: statistic.StatisticType_Robot_Fail, 272 Name: bot._cnfName, 273 }) 274 } 275 276 this._chan_bot_quit <- msg 277 }