From e3cdc0f53e2046cc1aafb2dfafa4bfec94f11cce Mon Sep 17 00:00:00 2001 From: shaoying Date: Tue, 2 Jul 2019 00:11:44 +0800 Subject: [PATCH] add test.cost --- bin/boot.sh | 3 +- src/contexts/cli/cli.go | 2 +- src/contexts/cli/version.go | 2 +- src/contexts/ctx/core.go | 15 ++-- src/contexts/nfs/nfs.go | 6 +- src/contexts/web/web.go | 1 - src/plugin/test.go | 149 +++++++++++++++++++++++++++++------- 7 files changed, 137 insertions(+), 41 deletions(-) diff --git a/bin/boot.sh b/bin/boot.sh index f979e0fc..f12197a0 100755 --- a/bin/boot.sh +++ b/bin/boot.sh @@ -68,7 +68,8 @@ log "dir:$dir" case $1 in install) shift && install "$@";; - start|"") shift && main "$@";; + start) shift && main "$@";; + "") main "$@";; create) mkdir -p $2; cd $2 && shift && shift && main "$@";; restart) action 30;; upgrade) action 31;; diff --git a/src/contexts/cli/cli.go b/src/contexts/cli/cli.go index 249ceba8..62713ee3 100644 --- a/src/contexts/cli/cli.go +++ b/src/contexts/cli/cli.go @@ -788,7 +788,7 @@ var version = struct { m.Cmdy("cli.system", m.Conf("runtime", "boot.ctx_bin"), "daemon", "cmd_dir", p, "cmd_env", "ctx_home", m.Conf("runtime", "boot.ctx_home"), - "cmd_env", "ctx_box", fmt.Sprintf("http://localhost%s", m.Conf("runtime", "boot.web_port")), + "cmd_env", "ctx_box", fmt.Sprintf("http://127.0.0.1%s", m.Conf("runtime", "boot.web_port")), "cmd_daemon", "true", ) return diff --git a/src/contexts/cli/version.go b/src/contexts/cli/version.go index bc866023..c2054e39 100644 --- a/src/contexts/cli/version.go +++ b/src/contexts/cli/version.go @@ -4,5 +4,5 @@ var version = struct { host string self int }{ - "2019-07-01 02:44:49", "com", 60, + "2019-07-01 20:57:35", "ZYB-20190522USI", 62, } diff --git a/src/contexts/ctx/core.go b/src/contexts/ctx/core.go index 94eebe7c..8c57184b 100644 --- a/src/contexts/ctx/core.go +++ b/src/contexts/ctx/core.go @@ -31,18 +31,19 @@ func (c *Context) Register(s *Context, x Server, args ...interface{}) { func (c *Context) Plugin(args []string) string { Index.Register(c, nil) m := &Message{code: 0, time: time.Now(), source: c, target: c, Meta: map[string][]string{}} + m.Option("log.disable", true) if len(args) == 0 { - m.Echo("%s: %s\n", c.Name, c.Help) + m.Echo("%s: %s\n\n", c.Name, c.Help) + m.Echo("命令列表:\n") for k, v := range c.Commands { - m.Echo("%s: %s %v\n", k, v.Name, v.Help) + m.Echo(" %s: %s\n %v\n\n", k, v.Name, v.Help) } - } else if cs, ok := c.Commands[args[0]]; ok { - h := cs.Hand - if e := h(m, c, args[0], args[1:]...); e != nil { - m.Echo("error: ").Echo("%v\n", e) + m.Echo("配置列表:\n") + for k, v := range c.Configs { + m.Echo(" %s(%v): %s\n", k, v.Value, v.Help) } } else { - m.Echo("error: ").Echo("not found: %v\n", args[0]) + m.Cmd(args) } return strings.Join(m.Meta["result"], "") } diff --git a/src/contexts/nfs/nfs.go b/src/contexts/nfs/nfs.go index be3acc37..dbdfcf60 100644 --- a/src/contexts/nfs/nfs.go +++ b/src/contexts/nfs/nfs.go @@ -972,7 +972,9 @@ func (nfs *NFS) Start(m *ctx.Message, arg ...string) bool { // 消息接收队列 msg, code, head, body := m, "0", "result", "append" - for bio := bufio.NewScanner(nfs.io); bio.Scan(); { + bio := bufio.NewScanner(nfs.io) + bio.Buffer(make([]byte, m.Confi("buf_size")), m.Confi("buf_size")) + for ; bio.Scan(); { m.TryCatch(m, true, func(m *ctx.Message) { switch field, value := nfs.Recv(bio.Text()); field { @@ -1124,7 +1126,7 @@ var Index = &ctx.Context{Name: "nfs", Help: "存储中心", }, }, Help: "读取文件的缓存区的大小"}, - "buf_size": &ctx.Config{Name: "buf_size", Value: "1024", Help: "读取文件的缓存区的大小"}, + "buf_size": &ctx.Config{Name: "buf_size", Value: "81920", Help: "读取文件的缓存区的大小"}, "dir_type": &ctx.Config{Name: "dir_type(file/dir/both/all)", Value: "both", Help: "dir命令输出的文件类型, file: 只输出普通文件, dir: 只输出目录文件, 否则输出所有文件"}, "dir_fields": &ctx.Config{Name: "dir_fields(time/type/name/size/line/hash)", Value: "time size line filename", Help: "dir命令输出文件名的类型, name: 文件名, tree: 带缩进的文件名, path: 相对路径, full: 绝对路径"}, diff --git a/src/contexts/web/web.go b/src/contexts/web/web.go index c012e868..ff6b2f9a 100644 --- a/src/contexts/web/web.go +++ b/src/contexts/web/web.go @@ -634,7 +634,6 @@ var Index = &ctx.Context{Name: "web", Help: "应用中心", kit.Structm(m.Magic("user", []string{"cookie", which}), func(key string, value string) { req.AddCookie(&http.Cookie{Name: key, Value: value}) m.Log("info", "set-cookie %s: %v", key, value) - }) if web.Client == nil { diff --git a/src/plugin/test.go b/src/plugin/test.go index 380427c8..faa41882 100644 --- a/src/plugin/test.go +++ b/src/plugin/test.go @@ -2,8 +2,10 @@ package main import ( "bufio" "bytes" + "sync/atomic" "contexts/ctx" "fmt" + "io" "io/ioutil" "net/http" "os" @@ -14,20 +16,23 @@ import ( kit "toolkit" ) -var Index = &ctx.Context{Name: "test", Help: "test", +var Index = &ctx.Context{Name: "test", Help: "接口测试工具", Caches: map[string]*ctx.Cache{}, Configs: map[string]*ctx.Config{ - "nread": {Name: "nread", Value: 1}, - "nwork": {Name: "nwork", Value: 10}, - "nskip": {Name: "nwork", Value: 100}, - "nwrite":{Name: "nwrite", Value: 1}, - "outdir": {Name: "outdir", Value: "tmp"}, - "prefix0": {Name: "prefix0", Value: "uri["}, - "prefix1": {Name: "prefix1", Value: "request_param["}, - "timeout": {Name: "timeout", Value: "10s"}, + "nread": {Name: "nread", Help: "读取Channel长度", Value: 1}, + "nwork": {Name: "nwork", Help: "协程数量", Value: 20}, + "limit":{Name: "limit", Help: "请求数量", Value: 100}, + "nskip": {Name: "nskip", Help: "请求限长", Value: 100}, + "nwrite":{Name: "nwrite", Help: "输出Channel长度", Value: 1}, + "outdir": {Name: "outdir", Help: "输出目录", Value: "tmp"}, + "prefix0": {Name: "prefix0", Help: "请求前缀", Value: "uri["}, + "prefix1": {Name: "prefix1", Help: "参数前缀", Value: "request_param["}, + "timeout": {Name: "timeout", Help: "请求超时", Value: "10s"}, }, Commands: map[string]*ctx.Command{ - "diff": {Name: "diff", Help:"diff", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) { + "diff": {Name: "diff file server1 server2", Help:"接口对比工具", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) { + os.MkdirAll(m.Conf("outdir"), 0777) + f, e := os.Open(arg[0]) m.Assert(e) defer f.Close() @@ -42,7 +47,7 @@ var Index = &ctx.Context{Name: "test", Help: "test", mu := sync.Mutex{} wg := sync.WaitGroup{} - all, skip, diff, same, error := 0, 0, 0, 0, 0 + var all, skip, diff, same, error int32 = 0, 0, 0, 0, 0 begin := time.Now() api := map[string]int{} @@ -96,20 +101,14 @@ var Index = &ctx.Context{Name: "test", Help: "test", size1, size2 := 0, 0 result := "error" - mu.Lock() - all++ - mu.Unlock() + atomic.AddInt32(&all, 1) var t3, t4 time.Duration if e1 != nil || e2 != nil { - mu.Lock() - error++ - mu.Unlock() + atomic.AddInt32(&error, 1) fmt.Printf("%d%% %d cost: %v/%v error: %v %v\n", int(count*100.0/total), error, t1, t2, e1, e2) } else if res1.StatusCode != http.StatusOK || res2.StatusCode != http.StatusOK { - mu.Lock() - error++ - mu.Unlock() + atomic.AddInt32(&error, 1) fmt.Printf("%d%% %d %s %s cost: %v/%v error: %v %v\n", int(count*100.0/total), error, "error", uri, t1, t2, res1.StatusCode, res2.StatusCode) } else { @@ -119,18 +118,14 @@ var Index = &ctx.Context{Name: "test", Help: "test", t3 = time.Since(begin) begin = time.Now() - num := 0 + var num int32 if bytes.Compare(b1, b2) == 0 { - mu.Lock() - same++ - mu.Unlock() + atomic.AddInt32(&same, 1) num = same result = "same" } else { - mu.Lock() - diff++ - mu.Unlock() + atomic.AddInt32(&diff, 1) num = diff result = "diff" @@ -196,7 +191,104 @@ var Index = &ctx.Context{Name: "test", Help: "test", m.Sort("time1", "int").Table() return }}, - "output": {Name: "output", Help:"output", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) { + "cost": {Name: "cost file server nroute", Help:"接口耗时测试", + Form: map[string]int{"nwork": 1, "limit": 1}, + Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) { + os.MkdirAll(m.Conf("outdir"), 0777) + + f, e := os.Open(arg[0]) + m.Assert(e) + defer f.Close() + + input := make(chan []string, kit.Int(m.Confx("nread"))) + output := make(chan []string, kit.Int(m.Confx("nwrite"))) + + count, nline := 0, 0 + + wg := sync.WaitGroup{} + limit := kit.Int(m.Confx("limit")) + + var skip, success int32 = 0, 0 + begin := time.Now() + api := map[string]int{} + go func() { + for bio := bufio.NewScanner(f); bio.Scan() && nline < limit; { + text := bio.Text() + count += len(text)+1 + + word := strings.Split(text, " ") + if len(word) != 2 { + continue + } + uri := word[0][len(m.Conf("prefix0")) : len(word[0])-1] + arg := word[1][len(m.Conf("prefix1")) : len(word[1])-1] + if len(arg) > m.Confi("nskip") { + skip++ + continue + } + + // fmt.Printf("line: %d %d%% %v\n", nline, int(nline/limit), uri) + nline++ + input <- []string{uri, arg, fmt.Sprintf("%d", nline)} + api[uri]++ + } + close(input) + wg.Wait() + close(output) + }() + + var times time.Duration + for i := 0; i < kit.Int(m.Confx("nwork")); i++ { + go func(msg *ctx.Message) { + wg.Add(1) + defer func() { + wg.Done() + }() + client := http.Client{Timeout:kit.Duration(m.Conf("timeout"))} + + for { + word, ok := <-input + if !ok { + break + } + uri, args, key := word[0], word[1], word[2] + + fmt.Printf("%v/%v\tpost: %v\t%v\n", key, limit, arg[1]+uri, args) + begin := time.Now() + res, err := client.Post(arg[1]+uri, "application/json", bytes.NewReader([]byte(args))) + if res.StatusCode == http.StatusOK { + io.Copy(ioutil.Discard, res.Body) + atomic.AddInt32(&success, 1) + } else { + fmt.Printf("%v/%v\terror: %v\n", key, limit, err) + } + times += time.Since(begin) + } + }(m.Spawn()) + } + + files := map[string]*os.File{} + for { + data, ok := <-output + if !ok { + break + } + + uri := data[1] + if files[uri] == nil { + f, _ := os.Create(path.Join(m.Conf("outdir"), strings.Replace(uri, "/", "_", -1)+".txt")) + defer f.Close() + files[uri] = f + } + for _, v:= range data { + fmt.Fprintf(files[uri], v) + } + } + m.Echo("\n\nnclient: %v skip: %v nreq: %v success: %v time: %v average: %vms", + m.Confx("nwork"), skip, nline, success, time.Since(begin), int(times)/nline/1000000) + return + }}, + "cmd": {Name: "cmd file", Help:"生成测试命令", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) { f, e := os.Open(arg[0]) m.Assert(e) defer f.Close() @@ -219,5 +311,6 @@ var Index = &ctx.Context{Name: "test", Help: "test", }, } func main() { + kit.DisableLog = true fmt.Print(Index.Plugin(os.Args[1:])) }