diff --git a/src/contexts/cli/cli.go b/src/contexts/cli/cli.go index e82880d0..903a7053 100644 --- a/src/contexts/cli/cli.go +++ b/src/contexts/cli/cli.go @@ -143,6 +143,9 @@ var Index = &ctx.Context{Name: "cli", Help: "管理中心", "action": &ctx.Config{Name: "action", Value: map[string]interface{}{}, Help: "交互任务"}, "project": &ctx.Config{Name: "project", Value: map[string]interface{}{ + // vim git golang + "ubuntu": map[string]interface{}{ + }, "github": "https://github.com/shylinux/context", "env": map[string]interface{}{ "GOPATH": "https://github.com/shylinux/context", @@ -613,9 +616,9 @@ var Index = &ctx.Context{Name: "cli", Help: "管理中心", defer func() { os.Exit(kit.Int(code)) }() - time.Sleep(time.Second * 1) m.Cmd("cli._exit") m.Cmd("nfs._exit") + time.Sleep(time.Second * 1) }) return }}, @@ -628,6 +631,8 @@ var Index = &ctx.Context{Name: "cli", Help: "管理中心", "project": &ctx.Command{Name: "project", Help: "", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) { switch arg[0] { + case "prepare": + case "init": if _, e := os.Stat(".git"); e == nil { m.Cmdp(0, []string{"git update"}, []string{"cli.system", "git"}, [][]string{ diff --git a/src/contexts/cli/version.go b/src/contexts/cli/version.go index 10ee19da..282f24ad 100644 --- a/src/contexts/cli/version.go +++ b/src/contexts/cli/version.go @@ -4,5 +4,9 @@ var version = struct { host string self int }{ +<<<<<<< Updated upstream "2019-07-08 23:23:11", "com.mac", 57, +======= + "2019-07-09 15:35:16", "ZYB-20190522USI", 123, +>>>>>>> Stashed changes } diff --git a/src/plugin/test.go b/src/plugin/test.go index 6e3d6f4c..ac35a87d 100644 --- a/src/plugin/test.go +++ b/src/plugin/test.go @@ -1,11 +1,12 @@ package main + import ( - "encoding/json" "bufio" "bytes" - "sync/atomic" - "contexts/ctx" + "encoding/json" "fmt" + "contexts/ctx" + kit "toolkit" "io" "io/ioutil" "net/http" @@ -13,313 +14,245 @@ import ( "path" "strings" "sync" + "sync/atomic" "time" - kit "toolkit" ) -var Index = &ctx.Context{Name: "test", Help: "接口测试工具", +func Input(m *ctx.Message, file string, input chan[]string) { + f, e := os.Open(file) + m.Assert(e) + defer f.Close() + + nline := 0 + for bio := bufio.NewScanner(f); nline < kit.Int(m.Confx("limit")) && bio.Scan(); { + word := strings.Split(bio.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") { + continue + } + + input <- []string{fmt.Sprintf("%d", nline), uri, arg} + if nline++; nline % kit.Int(m.Confx("nsleep")) == 0 { + fmt.Printf("nline:%d sleep 1s...\n", nline) + time.Sleep(time.Second) + } + } + close(input) +} + +func Output(m *ctx.Message, output <-chan[]string) { + os.MkdirAll(m.Conf("outdir"), 0777) + + 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) + } + } +} + +func Process(m *ctx.Message, file string, cb func(*ctx.Message, *http.Client, []string, chan []string)) (int32, time.Duration) { + nline, begin := int32(0), time.Now() + input := make(chan []string, kit.Int(m.Confx("nread"))) + output := make(chan []string, kit.Int(m.Confx("nwrite"))) + + go Input(m, file, input) + go Output(m, output) + + wg := sync.WaitGroup{} + for i := 0; i < m.Confi("nwork"); i++ { + go func(msg *ctx.Message) { + wg.Add(1) + defer wg.Done() + for { + word, ok := <-input + if !ok { + break + } + atomic.AddInt32(&nline, 1) + cb(msg, &http.Client{Timeout:kit.Duration(m.Conf("timeout"))}, word, output) + } + }(m.Spawn()) + } + wg.Wait() + close(output) + return nline, time.Since(begin) +} + +func Compare(b1 []byte, b2 []byte) bool { + if len(b1) != len(b2) { + return false + } + if bytes.Compare(b1, b2) == 0 { + return true + } + + var d1, d2 interface{} + json.Unmarshal(b1, &d1) + json.Unmarshal(b2, &d2) + s1, _ := json.Marshal(d1) + s2, _ := json.Marshal(d2) + if bytes.Compare(s1, s2) == 0 { + return true + } + return false +} + +var Index = &ctx.Context{Name: "test", Help: "测试工具", Caches: map[string]*ctx.Cache{}, Configs: map[string]*ctx.Config{ "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}, + "nsleep": {Name: "nsleep", Help: "阻塞时长", Value: "10000"}, "nwrite":{Name: "nwrite", Help: "输出Channel长度", Value: 1}, "outdir": {Name: "outdir", Help: "输出目录", Value: "tmp"}, + + "timeout": {Name: "timeout", Help: "请求超时", Value: "10s"}, "prefix0": {Name: "prefix0", Help: "请求前缀", Value: "uri["}, "prefix1": {Name: "prefix1", Help: "参数前缀", Value: "request_param["}, - "timeout": {Name: "timeout", Help: "请求超时", Value: "10s"}, - "nsleep": {Name: "nsleep", Help: "阻塞时长", Value: "10000"}, }, Commands: map[string]*ctx.Command{ - "diff": {Name: "diff file server1 server2", - Form: map[string]int{"nsleep": 1}, - Help:"接口对比工具", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) { - os.MkdirAll(m.Conf("outdir"), 0777) + "diff": {Name: "diff file server1 server2", Form: map[string]int{"nsleep": 1}, Help:"接口对比工具", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) { + if len(arg) < 3 { + m.Echo("usage: %v", "diff file server1 server2") + return + } - f, e := os.Open(arg[0]) - m.Assert(e) - defer f.Close() - http.DefaultClient.Timeout = kit.Duration(m.Conf("timeout")) - - input := make(chan []string, kit.Int(m.Confx("nread"))) - output := make(chan []string, kit.Int(m.Confx("nwrite"))) - - s, e := f.Stat() - m.Assert(e) - total, count, nline := int(s.Size()), 0, 0 - - mu := sync.Mutex{} - wg := sync.WaitGroup{} - var all, skip, diff, same, error int32 = 0, 0, 0, 0, 0 - - begin := time.Now() + var diff, same, error int32 = 0, 0, 0 api := map[string]int{} - go func() { - for bio := bufio.NewScanner(f); bio.Scan(); { - text := bio.Text() - count += len(text)+1 - // fmt.Printf("line: %d %d%% \n", nline, int(count*100.0/total)) + mu := sync.Mutex{} - 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 - } + nline, cost := Process(m, arg[0], func(msg *ctx.Message, client *http.Client, word []string, output chan []string) { + key, uri, args := word[0], word[1], word[2] + mu.Lock() + api[uri]++ + mu.Unlock() - nline++ - input <- []string{uri, arg, fmt.Sprintf("%d", nline)} - api[uri]++ - if nline % kit.Int(m.Confx("nsleep")) == 0 { - time.Sleep(time.Second) - fmt.Printf("sleep 1s...\n") - } - } - close(input) - wg.Wait() - close(output) - }() + begin := time.Now() + res1, e1 := client.Post(arg[1]+uri, "application/json", bytes.NewReader([]byte(args))) + t1 := time.Since(begin) - for i := 0; i < m.Confi("nwork"); i++ { - go func(msg *ctx.Message) { - wg.Add(1) - defer func() { - wg.Done() - }() + begin = time.Now() + res2, e2 := client.Post(arg[2]+uri, "application/json", bytes.NewReader([]byte(args))) + t2 := time.Since(begin) - for { - word, ok := <-input - if !ok { - break - } - uri, args, key := word[0], word[1], word[2] + size1, size2 := 0, 0 + result := "error" + var t3, t4 time.Duration + if e1 != nil || e2 != nil { + atomic.AddInt32(&error, 1) + fmt.Printf("%v %d cost: %v/%v error: %v %v\n", key, error, t1, t2, e1, e2) - begin := time.Now() - res1, e1 := http.Post(arg[1]+uri, "application/json", bytes.NewReader([]byte(args))) - t1 := time.Since(begin) + } else if res1.StatusCode != http.StatusOK || res2.StatusCode != http.StatusOK { + atomic.AddInt32(&error, 1) + fmt.Printf("%v %d %s %s cost: %v/%v error: %v %v\n", key, error, "error", uri, t1, t2, res1.StatusCode, res2.StatusCode) - begin = time.Now() - res2, e2 := http.Post(arg[2]+uri, "application/json", bytes.NewReader([]byte(args))) - t2 := time.Since(begin) + } else { + begin = time.Now() + b1, _ := ioutil.ReadAll(res1.Body) + b2, _ := ioutil.ReadAll(res2.Body) + t3 = time.Since(begin) - size1, size2 := 0, 0 - result := "error" - atomic.AddInt32(&all, 1) - var t3, t4 time.Duration - if e1 != nil || e2 != nil { - 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) + begin = time.Now() + var num int32 + if Compare(b1, b2) { + atomic.AddInt32(&same, 1) + num = same + result = "same" - } else if res1.StatusCode != http.StatusOK || res2.StatusCode != http.StatusOK { - 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 { + } else { + atomic.AddInt32(&diff, 1) + num = diff + result = "diff" - begin = time.Now() - b1, _ := ioutil.ReadAll(res1.Body) - b2, _ := ioutil.ReadAll(res2.Body) - t3 = time.Since(begin) - - begin = time.Now() - - var d1, d2 interface{} - json.Unmarshal(b1, &d1) - json.Unmarshal(b2, &d2) - s1, _ := json.Marshal(d1) - s2, _ := json.Marshal(d2) - var num int32 - if bytes.Compare(s1, s2) == 0 { - atomic.AddInt32(&same, 1) - num = same - result = "same" - - } else { - atomic.AddInt32(&diff, 1) - num = diff - result = "diff" - - result1 := []string{ - fmt.Sprintf("index:%v uri:", key), - fmt.Sprintf(uri), - fmt.Sprintf(" arguments:"), - fmt.Sprintf(args), - } - - result1 = append(result1, "\n") - result1 = append(result1, "\n") - result1 = append(result1, "result0:") - result1 = append(result1, string(b1)) - result1 = append(result1, "\n") - result1 = append(result1, "\n") - result1 = append(result1, "result1:") - result1 = append(result1, string(b2)) - result1 = append(result1, "\n") - result1 = append(result1, "\n") - output <- result1 - } - size1 = len(b1) - size2 = len(b2) - t4 = time.Since(begin) - fmt.Printf("%d%% %d %s %s size: %v/%v cost: %v/%v diff: %v/%v\n", int(count*100.0/total), num, result, uri, len(b1), len(b2), t1, t2, t3, t4) + result1 := []string{ + fmt.Sprintf("index:%v uri:", key), + fmt.Sprintf(uri), + fmt.Sprintf(" arguments:"), + fmt.Sprintf(args), } - mu.Lock() - m.Add("append", "uri", uri) - m.Add("append", "time1", t1/1000000) - m.Add("append", "time2", t2/1000000) - m.Add("append", "time3", t3/1000000) - m.Add("append", "time4", t4/1000000) - m.Add("append", "size1", size1) - m.Add("append", "size2", size2) - m.Add("append", "action", result) - mu.Unlock() + result1 = append(result1, "\n") + result1 = append(result1, "\n") + result1 = append(result1, "result0:") + result1 = append(result1, string(b1)) + result1 = append(result1, "\n") + result1 = append(result1, "\n") + result1 = append(result1, "result1:") + result1 = append(result1, string(b2)) + result1 = append(result1, "\n") + result1 = append(result1, "\n") + output <- result1 } - }(m.Spawn()) - } - - files := map[string]*os.File{} - for { - data, ok := <-output - if !ok { - break + size1 = len(b1) + size2 = len(b2) + t4 = time.Since(begin) + fmt.Printf("%v %d %s %s size: %v/%v cost: %v/%v diff: %v/%v\n", key, num, result, uri, len(b1), len(b2), t1, t2, t3, t4) } - 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) - } - } + mu.Lock() + m.Add("append", "uri", uri) + m.Add("append", "time1", t1/1000000) + m.Add("append", "time2", t2/1000000) + m.Add("append", "time3", t3/1000000) + m.Add("append", "time4", t4/1000000) + m.Add("append", "size1", size1) + m.Add("append", "size2", size2) + m.Add("append", "action", result) + mu.Unlock() + }) - fmt.Printf("\n\nnuri: %v nreq: %v skip: %v same: %v diff: %v error: %v cost: %v\n\n", len(api), nline, skip, same, diff, error, time.Since(begin)) + fmt.Printf("\n\nnuri: %v nreq: %v same: %v diff: %v error: %v cost: %v\n\n", len(api), nline, same, diff, error, cost) m.Sort("time1", "int").Table() return }}, - "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) - }() - + "cost": {Name: "cost file server nroute", Help:"接口耗时测试", Form: map[string]int{"nwork": 1, "limit": 1, "nsleep": 1}, Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) { + var success int32 = 0 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"))} + limit := kit.Int(m.Confx("limit")) + nline, cost := Process(m, arg[0], func(msg *ctx.Message, client *http.Client, word []string, output chan []string) { + key, uri, args := word[0], word[1], word[2] + fmt.Printf("%v/%v post: %v\t%v\n", key, limit, arg[1]+uri, args) - 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 + 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 error: %v\n", key, limit, err) } + times += time.Since(begin) + }) - 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) + m.Echo("\n\nnclient: %v nreq: %v success: %v time: %v average: %vms", + m.Confx("nwork"), nline, success, cost, int(times)/int(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() - for bio := bufio.NewScanner(f); bio.Scan(); { - text := bio.Text() - - 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") { - continue - } - m.Echo("./hey -n 10000 -c 100 -m POST -T \"application/json\" -d '%s' http://127.0.0.1:6363%s\n", arg, uri) - } + str := kit.Select("./hey -n 10000 -c 100 -m POST -T \"application/json\" -d '%s' http://127.0.0.1:6363%s\n", arg, 1) + Process(m, arg[0], func(msg *ctx.Message, client *http.Client, word []string, output chan []string) { + m.Echo(str, word[2], word[1]) + }) return }}, }, diff --git a/usr/librarys/example.js b/usr/librarys/example.js index 8eea5ef9..199fa7ae 100644 --- a/usr/librarys/example.js +++ b/usr/librarys/example.js @@ -664,6 +664,8 @@ function Plugin(page, pane, field) { item.ondblclick = function(event) { action.value = kit.History.get("txt", -1).data.trim() } + item.autocomplete = "off" + } args && count < args.length && (item.value = args[count++]||item.value||"") item.className = "args"