go_dreamfactory/stress/robot/robot.go
2022-12-08 15:51:07 +08:00

460 lines
11 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package robot
import (
"bytes"
"encoding/json"
"fmt"
"go_dreamfactory/comm"
"go_dreamfactory/pb"
"io"
"math/rand"
"os"
"strconv"
"time"
"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) { // 记录错误码
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() int64 {
var byteLen int64
mainType := "user"
subType := "create"
msg := &pb.UserMessage{MainType: mainType, SubType: subType}
rand.Seed(time.Now().UnixNano())
n2 := rand.Int63n(9000000)
name := strconv.Itoa(int(n2) + 100000)
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) { // 记录错误码
byteLen = 0
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
}