支持测试接口连续调用

This commit is contained in:
zhaocy 2022-07-13 16:17:33 +08:00
parent a7ad82c776
commit fb3a2ce08a
11 changed files with 131 additions and 80 deletions

View File

@ -77,9 +77,10 @@ var (
},
rsp: &pb.FriendBlackAddResp{},
// enabled: true,
next: func(rsp proto.Message, handle func(nextCase *TestCase)) {
next: func(robot *Robot, rsp proto.Message) {
tcs := []*TestCase{}
if r, ok := rsp.(*pb.FriendBlackAddResp); ok {
handle(&TestCase{
tc := &TestCase{
desc: "删除黑名单",
mainType: string(comm.ModuleFriend),
subType: friend.FriendSubTypeDelBlack,
@ -88,8 +89,11 @@ var (
},
rsp: &pb.FriendDelBlackResp{},
enabled: true,
})
}
tcs = append(tcs, tc)
robot.AddTestCases(tcs)
}
},
}, {
desc: "删除黑名单",
@ -104,6 +108,5 @@ var (
//声明加入到构建器并发起请求
func (r *Robot) RunFriend() {
r.addBuilders(friendBuilders)
r.batchHandleReq()
r.AddTestCases(friendBuilders)
}

View File

@ -24,7 +24,31 @@ var (
fmt.Printf("%d- %v\n", (i + 1), v)
}
},
// enabled: true,
enabled: true,
next: func(robot *Robot, rsp proto.Message) {
tcs := []*TestCase{}
if r, ok := rsp.(*pb.HeroListResp); ok {
for _, v := range r.List {
tc := &TestCase{
desc: "英雄详情",
mainType: string(comm.ModuleHero),
subType: hero.HeroSubTypeInfo,
req: &pb.HeroInfoReq{
HeroId: v.Id,
},
rsp: &pb.HeroInfoResp{},
enabled: true,
print: func(rsp proto.Message) {
r := rsp.(*pb.HeroInfoResp)
fmt.Printf("%v\n", r)
},
}
tcs = append(tcs, tc)
}
robot.AddTestCases(tcs)
}
},
}, {
desc: "英雄详情",
mainType: string(comm.ModuleHero),
@ -41,7 +65,7 @@ var (
req: &pb.HeroChoukaReq{
HeroIds: []int32{42911},
},
rsp: &pb.HeroChoukaResp{},
rsp: &pb.HeroChoukaResp{},
// enabled: true,
}, {
mainType: string(comm.ModuleHero),
@ -72,6 +96,5 @@ var (
//声明加入到构建器并发起请求
func (r *Robot) RunHero() {
r.addBuilders(heroBuilders)
r.batchHandleReq()
r.AddTestCases(heroBuilders)
}

View File

@ -39,6 +39,8 @@ func (r *Robot) AccountLogin() {
log.Printf("区服:[%d] 账号:[%s] login...", r.opts.ServerId, r.opts.Account)
builders := []*TestCase{
{
id: "login",
desc: "登录",
mainType: string(comm.ModuleUser),
subType: user.UserSubTypeLogin,
req: &pb.UserLoginReq{
@ -47,23 +49,26 @@ func (r *Robot) AccountLogin() {
},
rsp: &pb.UserLoginResp{},
enabled: true,
next: func(rsp proto.Message, handle func(nextCase *TestCase)) {
next: func(r *Robot, rsp proto.Message) {
tcs := []*TestCase{}
if _, ok := rsp.(*pb.UserLoginResp); ok {
nick := randomdata.SillyName()
handle(&TestCase{
tc := &TestCase{
desc: "创角",
mainType: string(comm.ModuleUser),
subType: user.UserSubTypeCreate,
req: &pb.UserCreateReq{ //设置请求参数
NickName: nick,
},
rsp: &pb.UserCreateResp{},
enabled: true,
})
rsp: &pb.UserCreateResp{},
// enabled: true,
}
tcs = append(tcs, tc)
r.AddTestCases(tcs)
}
},
},
}
r.addBuilders(builders)
r.batchHandleReq()
r.AddTestCases(builders)
}

View File

@ -8,9 +8,10 @@ import (
var notify_builders = []*TestCase{
{
//create
desc: "全局通知",
mainType: comm.MainTypeNotify,
subType: comm.SubTypeErrorNotify,
rsp: &pb.NotifyErrorNotifyPush{},
rsp: &pb.NotifyErrorNotifyPush{},
enabled: true,
},
}

View File

@ -19,6 +19,5 @@ var pack_builders = []*TestCase{
//声明加入到构建器并发起请求
func (r *Robot) RunPack() {
r.addBuilders(pack_builders)
r.batchHandleReq()
r.AddTestCases(pack_builders)
}

View File

@ -14,17 +14,18 @@ import (
"github.com/gorilla/websocket"
jsoniter "github.com/json-iterator/go"
uuid "github.com/satori/go.uuid"
"google.golang.org/protobuf/proto"
)
type Robot struct {
ws *websocket.Conn
opts *Options
user *pb.DBUser
builders []*TestCase //测试用例
linkCase *LinkCase //测试用例链,适应于用例跑批
wg sync.WaitGroup
ws *websocket.Conn
opts *Options
user *pb.DBUser
builderMap map[string]*TestCase
// linkCase *LinkCase
wg sync.WaitGroup
ch chan string //uuid
}
func NewRobot(opts *Options) *Robot {
@ -33,9 +34,10 @@ func NewRobot(opts *Options) *Robot {
log.Fatal(err)
}
r := &Robot{
ws: ws,
opts: opts,
linkCase: NewLinkCase(),
ws: ws,
opts: opts,
builderMap: make(map[string]*TestCase),
ch: make(chan string, 10),
}
return r
@ -69,90 +71,102 @@ func (r *Robot) Run() {
}
}()
// select {}
r.wg.Wait()
}
type TestCase struct {
desc string
mainType string
subType string
req proto.Message
rsp proto.Message
enabled bool
start time.Time
requested bool //请求标识 true已发
print func(rsp proto.Message) //定义打印
next func(rsp proto.Message, handle func(nextCase *TestCase))
id string //uuid
desc string //用例描述
mainType string //协议类型 L1
subType string //协议类型 L2
req proto.Message //请求类型
rsp proto.Message //响应类型
enabled bool //是否启用
start time.Time //启用时间
requested bool //是否已请求 //请求标识 true已发
print func(rsp proto.Message) //定义打印
next func(robot *Robot, rsp proto.Message) //处理下一层用例请求
}
//添加测试用用例
func (r *Robot) addBuilders(builders []*TestCase) {
for _, b := range builders {
if b.enabled {
r.builders = append(r.builders, b)
if b.id == "" {
uuid := uuid.NewV4().String()
b.id = uuid
r.builderMap[uuid] = b
} else {
r.builderMap[b.id] = b
}
}
}
}
func (r *Robot) handleReq(b *TestCase) {
b.requested = true
b.start = time.Now()
head := &pb.UserMessage{MainType: b.mainType, SubType: b.subType}
defer traceFunc(head.MainType, head.SubType, r.user.GetUid(), b.req)
err := r.SendToClient(head, b.req)
if err != nil {
log.Fatal(err)
//处理用例,发送请求
func (r *Robot) handleReq() {
for _, b := range r.builderMap {
if b.enabled && b.req != nil && !b.requested {
r.wg.Add(1)
time.Sleep(time.Second * 1)
b.start = time.Now()
head := &pb.UserMessage{MainType: b.mainType, SubType: b.subType}
defer traceFunc(head.MainType, head.SubType, r.user.GetUid(), b.req)
err := r.SendToClient(head, b.req)
if err != nil {
log.Fatal(err)
}
b.requested = true
r.ch <- b.id
}
}
}
//执行请求
func (r *Robot) batchHandleReq() {
for _, b := range r.builders {
if b.req != nil && !b.requested {
r.wg.Add(1)
time.Sleep(time.Second * 1)
r.handleReq(b)
}
}
func (r *Robot) AddTestCases(tcs []*TestCase) {
r.addBuilders(tcs)
r.handleReq()
}
//执行响应
func (r *Robot) batchhandleRsp(msg *pb.UserMessage) {
for i, b := range r.builders {
if b.enabled && (msg.MainType == b.mainType &&
msg.SubType == b.subType) {
if !comm.ProtoUnmarshal(msg, b.rsp) {
uuid := <-r.ch
if v, ok := r.builderMap[uuid]; ok {
if v.enabled &&
(msg.MainType == v.mainType &&
msg.SubType == v.subType) &&
v.requested {
if !comm.ProtoUnmarshal(msg, v.rsp) {
return
}
if b.print == nil {
printReply(msg, b)
if v.print == nil {
printReply(msg, v)
} else {
fmt.Printf("===== %s [%s.%s] =====\n", b.desc, msg.MainType, msg.SubType)
b.print(b.rsp)
fmt.Println()
fmt.Printf("===== %s [%s.%s]=====\n", v.desc, msg.MainType, msg.SubType)
v.print(v.rsp)
fmt.Println("==============================")
}
if b.next != nil {
b.next(b.rsp, r.handleReq)
if v.next != nil {
v.next(r, v.rsp)
}
if msg.MainType == "user" && msg.SubType == "login" {
r.loginCallback(b.rsp)
r.loginCallback(v.rsp)
} else {
if b.requested {
r.builders = append(r.builders[:i], r.builders[i+1:]...)
}
delete(r.builderMap, v.id)
}
r.wg.Done()
}
}
}
//登录回调
func (r *Robot) loginCallback(rsp proto.Message) {
r.builders = append(r.builders[:0], r.builders[1:]...)
delete(r.builderMap, "login")
lr := rsp.(*pb.UserLoginResp)
if lr.Data != nil {
r.user = lr.Data
@ -232,8 +246,7 @@ func (r *Robot) AccountRegister(account string, sid int32) {
enabled: true,
},
}
r.addBuilders(user_builders)
r.batchHandleReq()
r.AddTestCases(user_builders)
}
}

View File

@ -62,6 +62,5 @@ var (
//声明加入到构建器并发起请求
func (r *Robot) RunTask() {
r.addBuilders(taskBuilders)
r.batchHandleReq()
r.AddTestCases(taskBuilders)
}

View File

@ -36,6 +36,5 @@ var user_builders = []*TestCase{
//声明加入到构建器并发起请求
func (r *Robot) RunUser() {
r.addBuilders(user_builders)
r.batchHandleReq()
r.AddTestCases(user_builders)
}

View File

@ -1,6 +1,7 @@
package hero
import (
"fmt"
"go_dreamfactory/comm"
"go_dreamfactory/pb"
"go_dreamfactory/utils"
@ -28,15 +29,17 @@ func (this *apiComp) Info(session comm.IUserSession, req *pb.HeroInfoReq) (code
code = pb.ErrorCode_SystemError
return
}
utils.TraceFunc(session.GetUserId(), string(this.module.GetType()), HeroSubTypeList, req, rsp)
utils.TraceFunc(session.GetUserId(), string(this.module.GetType()), HeroSubTypeInfo, req, rsp)
}()
hero := this.module.modelHero.getOneHero(session.GetUserId(), req.HeroId)
if hero == nil {
code = pb.ErrorCode_HeroNoExist
return
}
rsp.Base = hero
fmt.Printf("[ %v ] \n", hero)
return
}

View File

@ -154,6 +154,9 @@ func (this *ModelHero) consumeOneHeroCard(uid, heroId string, count int32) (err
//更新英雄数据
func (this *ModelHero) modifyHeroData(uid, heroId string, data map[string]interface{}) error {
if len(data) == 0 {
return fmt.Errorf("params len is 0")
}
return this.moduleHero.modelHero.ChangeList(uid, heroId, data)
}

View File

@ -114,6 +114,9 @@ func (this *User) AddAttributeValue(uid string, attr string, add int32) (code pb
update[comm.ResDiamond] = user.Diamond + add
}
if len(update) == 0 {
return
}
if err := this.modelUser.updateUserAttr(uid, update); err != nil {
log.Errorf("AddAttributeValue err:%v", err)
code = pb.ErrorCode_DBError