package robot import ( "bytes" "encoding/json" "fmt" "go_dreamfactory/comm" "go_dreamfactory/pb" "io" "os" "strconv" "github.com/gorilla/websocket" "github.com/sirupsen/logrus" "google.golang.org/protobuf/proto" ) type Robot struct { ws *websocket.Conn account string sid string user *pb.DBUser } var zlog *logrus.Logger func initlog() { zlog = logrus.New() zlog.SetLevel(logrus.DebugLevel) zlog.SetFormatter(&RobotFormatter{ DisableTimestamp: true, DisableQuote: true, }) //设置output,默认为stderr,可以为任何io.Writer,比如文件*os.File file, err := os.OpenFile("robot.log", os.O_CREATE|os.O_WRONLY|os.O_TRUNC, 0666) writers := []io.Writer{ file, os.Stdout} //同时写文件和屏幕 fileAndStdoutWriter := io.MultiWriter(writers...) if err == nil { zlog.SetOutput(fileAndStdoutWriter) } else { zlog.Info("failed to log to file.") } } func NewRobot(url string) *Robot { initlog() ws, _, err := websocket.DefaultDialer.Dial(url, nil) if err != nil { zlog.Fatalf("websocket conn err:%v", err) } r := &Robot{ ws: ws, sid: "df01", } r.account = r.RandStr1(13) return r } type TestCase struct { id string //用例ID 如果没有指定,会自动赋值uuid desc string //用例描述 mainType string //协议类型 L1 subType string //协议类型 L2 req proto.Message //请求类型 rsp proto.Message //响应类型 } //加入用例并执行请求 func (r *Robot) addTestCaseAndReq(tcs []*TestCase) { } //错误通知处理 func (r *Robot) handleNotify(uuid string, msg *pb.UserMessage) { if msg.MainType == "notify" && msg.SubType == "errornotify" { rsp := &pb.NotifyErrorNotifyPush{} if !comm.ProtoUnmarshal(msg, rsp) { return } } } //处理响应 func (r *Robot) handleRsp(id string) { var msg *pb.UserMessage = &pb.UserMessage{} _, data, err := r.ws.ReadMessage() if err != nil { zlog.Fatalf("readMessage err:%v", err) } if err = proto.Unmarshal(data, msg); err != nil { zlog.Fatalf("unmarshal err:%v", err) } } //登录回调 func (r *Robot) loginCallback(rsp proto.Message) { //清除登录用例 lr := rsp.(*pb.UserLoginResp) if lr.Data != nil { r.user = lr.Data r.onUserLoaded() } } //发送消息 func (r *Robot) SendToClient(msg *pb.UserMessage, rsp proto.Message) error { //模拟客户端 每次请求都会生成新的秘钥 msg.Sec = r.BuildSecStr() if comm.ProtoMarshal(rsp, msg) { data, _ := proto.Marshal(msg) return r.ws.WriteMessage(websocket.BinaryMessage, data) } return nil } //格式化json func formatJson(data string) (string, error) { var out bytes.Buffer err := json.Indent(&out, []byte(data), "", " ") return out.String(), err } //方法参数跟踪 func traceFunc(module string, funcName string, uid string, funcArgs interface{}) { zlog.Debugf("req [%s.%s] [%s] [%v]", module, funcName, uid, funcArgs) } //在这里添加玩家成功登录以后的测试方法 //次方法在用户登录成功后调用 func (r *Robot) onUserLoaded() { //user //r.RunUser() } type RobotFormatter struct { DisableTimestamp bool DisableQuote bool } func (r *RobotFormatter) Format(entry *logrus.Entry) ([]byte, error) { var b *bytes.Buffer if entry.Buffer != nil { b = entry.Buffer } else { b = &bytes.Buffer{} } var timestamp string var newLog string if !r.DisableTimestamp { timestamp = entry.Time.Format("2006-01-02 15:04:05") newLog = fmt.Sprintf("[%s] %s\n", timestamp, entry.Message) } else { newLog = fmt.Sprintf("%s\n", entry.Message) } b.WriteString(newLog) return b.Bytes(), nil } func (r *Robot) MessageRsp(mainType, subType string) (bool, int64) { var byteLen int64 var msg *pb.UserMessage = &pb.UserMessage{} _, data, err := r.ws.ReadMessage() if err != nil { fmt.Printf("readMessage err:%v", err) return false, byteLen } byteLen = int64(len(data)) if err = proto.Unmarshal(data, msg); err != nil { fmt.Printf("unmarshal err:%v", err) } //fmt.Printf("接收消息=====msg.MainType = %s,msg.SubType = %s\n", msg.MainType, msg.SubType) if msg.MainType == "chat" && msg.SubType == "message" { resp := &pb.ChatMessagePush{} if !comm.ProtoUnmarshal(msg, resp) { return false, byteLen } return false, byteLen //fmt.Printf("接收消息=====resp:%v\n", resp.Chat) } else if msg.MainType == "user" && msg.SubType == "login" { resp := &pb.UserLoginResp{} if !comm.ProtoUnmarshal(msg, resp) { return false, byteLen } //fmt.Printf("接收消息=====loginData:%v,userExpand:%v\n", resp.Data, resp.Ex) return true, byteLen } else if msg.MainType == "user" && msg.SubType == "create" { resp := &pb.UserCreateResp{} if !comm.ProtoUnmarshal(msg, resp) { return false, byteLen } //fmt.Printf("接收消息=====loginData:%v,userExpand:%v\n", resp.Data, resp.Ex) return true, byteLen } else if msg.MainType == "gourmet" && msg.SubType == "getranduser" { resp := &pb.GourmetGetRandUserResp{} if !comm.ProtoUnmarshal(msg, resp) { return false, byteLen } return false, byteLen } else if msg.MainType == "gourmet" && msg.SubType == "getlist" { resp := &pb.GourmetGetRandUserResp{} if !comm.ProtoUnmarshal(msg, resp) { return false, byteLen } return true, byteLen } return false, byteLen } func (r *Robot) CloseHandler() { r.ws.Close() } func (r *Robot) GetMessagedata() (data []byte, err error) { _, data, err = r.ws.ReadMessage() if err != nil { fmt.Printf("readMessage err:%v", err) } return data, err } func (r *Robot) Login() int64 { var byteLen int64 msg := &pb.UserMessage{MainType: "user", SubType: "login"} rsp := &pb.UserLoginReq{ Account: "user001", Sid: "dfmxf", } msg.Sec = r.BuildSecStr() if comm.ProtoMarshal(rsp, msg) { data, _ := proto.Marshal(msg) r.ws.WriteMessage(websocket.BinaryMessage, data) } for { var msg *pb.UserMessage = &pb.UserMessage{} _, data, err := r.ws.ReadMessage() if err != nil { fmt.Printf("readMessage err:%v", err) continue } if err = proto.Unmarshal(data, msg); err != nil { fmt.Printf("unmarshal err:%v", err) } if msg.MainType == "user" && msg.SubType == "login" { byteLen += int64(len(data)) resp := &pb.UserLoginResp{} if !comm.ProtoUnmarshal(msg, resp) { //反序列化失败 break } break } else if msg.MainType == "notify" && msg.SubType == "errornotify" { rsp := &pb.NotifyErrorNotifyPush{} if !comm.ProtoUnmarshal(msg, rsp) { // 记录错误码 fmt.Printf("NotifyErrorNotifyPush err:%v", rsp) byteLen = 0 break } } } return byteLen } func (r Robot) GetRandUser() bool { mainType := "gourmet" subType := "getranduser" msg := &pb.UserMessage{MainType: mainType, SubType: subType} rsp := &pb.GourmetGetRandUserReq{ People: 3, } msg.Sec = r.BuildSecStr() if comm.ProtoMarshal(rsp, msg) { data, _ := proto.Marshal(msg) err := r.ws.WriteMessage(websocket.BinaryMessage, data) if err != nil { fmt.Printf("WriteMessage err:%v", err) } } for { if b, _ := r.MessageRsp(mainType, subType); b { return true } } //return true } func (r *Robot) Create(i uint64) int64 { var byteLen int64 mainType := "user" subType := "create" msg := &pb.UserMessage{MainType: mainType, SubType: subType} name := "e100000" + strconv.Itoa(int(i)) + r.account rsp := &pb.UserCreateReq{ NickName: name, Figure: 100, Gender: 0, } msg.Sec = r.BuildSecStr() if comm.ProtoMarshal(rsp, msg) { data, _ := proto.Marshal(msg) err := r.ws.WriteMessage(websocket.BinaryMessage, data) if err != nil { fmt.Printf("WriteMessage err:%v", err) } } for { var msg *pb.UserMessage = &pb.UserMessage{} _, data, err := r.ws.ReadMessage() if err != nil { fmt.Printf("readMessage err:%v", err) continue } if err = proto.Unmarshal(data, msg); err != nil { fmt.Printf("unmarshal err:%v", err) } if msg.MainType == "user" && msg.SubType == "create" { byteLen += int64(len(data)) resp := &pb.UserCreateResp{} if !comm.ProtoUnmarshal(msg, resp) { //反序列化失败 break } break } else if msg.MainType == "notify" && msg.SubType == "errornotify" { rsp := &pb.NotifyErrorNotifyPush{} if !comm.ProtoUnmarshal(msg, rsp) { // 记录错误码 fmt.Printf("NotifyErrorNotifyPush err:%v", rsp) byteLen = 0 break } break } } return byteLen } // 获取美食家信息列表数据 func (r Robot) GetGourmetList() { mainType := "gourmet" subType := "getlist" msg := &pb.UserMessage{MainType: mainType, SubType: subType} rsp := &pb.GourmetGetListReq{} msg.Sec = r.BuildSecStr() if comm.ProtoMarshal(rsp, msg) { data, _ := proto.Marshal(msg) err := r.ws.WriteMessage(websocket.BinaryMessage, data) if err != nil { fmt.Printf("WriteMessage err:%v", err) } } // for { // var msg *pb.UserMessage = &pb.UserMessage{} // _, data, err := r.ws.ReadMessage() // if err != nil { // fmt.Printf("readMessage err:%v", err) // continue // } // if err = proto.Unmarshal(data, msg); err != nil { // fmt.Printf("unmarshal err:%v", err) // } // if msg.MainType == mainType && msg.SubType == subType { // byteLen += int64(len(data)) // resp := &pb.GourmetGetListResp{} // if !comm.ProtoUnmarshal(msg, resp) { //反序列化失败 // break // } // break // } // } return } // addItem func (r Robot) AddGrormetItem() bool { mainType := "gm" subType := "cmd" msg := &pb.UserMessage{MainType: mainType, SubType: subType} rsp := &pb.GMCmdReq{ Cmod: "bingo:item,10002,100", } msg.Sec = r.BuildSecStr() if comm.ProtoMarshal(rsp, msg) { data, _ := proto.Marshal(msg) err := r.ws.WriteMessage(websocket.BinaryMessage, data) if err != nil { fmt.Printf("WriteMessage err:%v", err) } } return true } func (r *Robot) SetAccount(account string) { r.account = account } func (r Robot) GourmetOrder() int64 { var byteLen int64 mainType := "gourmet" subType := "createorder" msg := &pb.UserMessage{MainType: mainType, SubType: subType} rsp := &pb.GourmetCreateOrderReq{} rsp.Order = append(rsp.Order, &pb.OrderCook{ FoodType: 1001, FoodCount: 10, }) msg.Sec = r.BuildSecStr() if comm.ProtoMarshal(rsp, msg) { data, _ := proto.Marshal(msg) err := r.ws.WriteMessage(websocket.BinaryMessage, data) if err != nil { fmt.Printf("WriteMessage err:%v", err) } } for { var msg *pb.UserMessage = &pb.UserMessage{} _, data, err := r.ws.ReadMessage() if err != nil { fmt.Printf("readMessage err:%v", err) continue } if err = proto.Unmarshal(data, msg); err != nil { fmt.Printf("unmarshal err:%v", err) } if msg.MainType == mainType && msg.SubType == subType { byteLen += int64(len(data)) resp := &pb.GourmetCreateOrderResp{} if !comm.ProtoUnmarshal(msg, resp) { //反序列化失败 break } break } } return byteLen } // 抽卡压测 参数 0~4 0 普通抽 func (r *Robot) DrawCard(drawType int32) int64 { var byteLen int64 mainType := "hero" subType := "drawcard" msg := &pb.UserMessage{MainType: mainType, SubType: subType} rsp := &pb.HeroDrawCardReq{ DrawType: drawType, DrawCount: 10, } msg.Sec = r.BuildSecStr() if comm.ProtoMarshal(rsp, msg) { data, _ := proto.Marshal(msg) err := r.ws.WriteMessage(websocket.BinaryMessage, data) if err != nil { fmt.Printf("WriteMessage err:%v", err) } } for { var msg *pb.UserMessage = &pb.UserMessage{} _, data, err := r.ws.ReadMessage() if err != nil { fmt.Printf("readMessage err:%v", err) continue } if err = proto.Unmarshal(data, msg); err != nil { fmt.Printf("unmarshal err:%v", err) } if msg.MainType == mainType && msg.SubType == subType { byteLen += int64(len(data)) resp := &pb.UserCreateResp{} if !comm.ProtoUnmarshal(msg, resp) { //反序列化失败 byteLen = 0 } break } else if msg.MainType == "notify" && msg.SubType == "errornotify" { rsp := &pb.NotifyErrorNotifyPush{} if !comm.ProtoUnmarshal(msg, rsp) { // 记录错误码 fmt.Printf("NotifyErrorNotifyPush ProtoUnmarshal err") } byteLen = 0 break } } return byteLen }