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  }