package formview import ( "bytes" "fmt" "go_dreamfactory/cmd/v2/lib/common" pb2 "go_dreamfactory/cmd/v2/lib/pb" "go_dreamfactory/cmd/v2/model" "go_dreamfactory/cmd/v2/service" "go_dreamfactory/cmd/v2/service/observer" "go_dreamfactory/comm" "go_dreamfactory/pb" "go_dreamfactory/utils" "os" "path/filepath" "strings" "sync" "sync/atomic" cfg "go_dreamfactory/sys/configure/structs" "fyne.io/fyne/v2" "fyne.io/fyne/v2/container" "fyne.io/fyne/v2/dialog" "fyne.io/fyne/v2/widget" "github.com/sirupsen/logrus" "github.com/spf13/cast" ) type RtaskTestView struct { BaseformView itemList *common.ItemList resultCount int32 //结果条数 resultChan chan string //结果内容 flag bool msgs []string reportPath string //Json Data数据路径 } func (this *RtaskTestView) CreateView(t *model.TestCase) fyne.CanvasObject { defer this.loadProtocol() this.itemList = common.NewItemList() this.itemList.ItemList = this.itemList.CreateDefaultCheckList() this.resultChan = make(chan string) rtaskTypeInput := widget.NewEntry() paramsInput := widget.NewEntry() paramsInput.PlaceHolder = "多个数值使用,分隔" condiInput := widget.NewEntry() condiInput.PlaceHolder = "条件ID为空时走触发逻辑否则走校验逻辑" input := widget.NewEntry() input.PlaceHolder = "分组编号" this.form.AppendItem(widget.NewFormItem("任务类型", rtaskTypeInput)) this.form.AppendItem(widget.NewFormItem("参数", paramsInput)) this.form.AppendItem(widget.NewFormItem("条件ID", condiInput)) this.form.AppendItem(widget.NewFormItem("分组编号", input)) testBtn := widget.NewButton("手动触发", func() { this.form.OnSubmit = func() { if err := service.GetPttService().SendToClient( t.MainType, t.SubType, &pb.RtaskTestReq{ RtaskType: cast.ToInt32(rtaskTypeInput.Text), Params: utils.TrInt32(paramsInput.Text), CondiId: cast.ToInt32(condiInput.Text), }, ); err != nil { logrus.Error(err) return } } paiWin := dialog.NewCustom("手动触发", "关闭", this.form, this.w) paiWin.Resize(fyne.NewSize(600, 300)) paiWin.Show() }) //"F:\\projects\\workspace\\go_dreamfactory\\bin\\json" jsonPathEntry := widget.NewEntry() jsonPathEntry.SetText("F:\\projects\\workspace\\go_dreamfactory\\bin\\json") reportEntry := widget.NewEntry() reportEntry.SetText("F:\\") autoTestForm := widget.NewForm( widget.NewFormItem("Json配置", jsonPathEntry), widget.NewFormItem("报告保存", reportEntry), ) autoTestForm.OnSubmit = func() { commCfg := &common.Config{ Path: jsonPathEntry.Text, } this.reportPath = reportEntry.Text var wg sync.WaitGroup if tb, err := cfg.NewTables(commCfg.Loader); err == nil { for _, v := range tb.RdtaskCondi.GetDataList() { wg.Add(1) params := []int32{v.Data1, v.Data2, v.Data3, v.Data4, v.Data5} var p []int32 for _, v := range params { if v > 0 { p = append(p, v) } } go func(condId, rtype int32, p []int32) { defer wg.Done() if err := service.GetPttService().SendToClient( t.MainType, t.SubType, &pb.RtaskTestReq{ RtaskType: rtype, Params: p, }, ); err != nil { logrus.Error(err) return } // logrus.Debugf("执行任务 id:%v rtype:%v params:%v", condId, rtype, p) // msgs = append(msgs, fmt.Sprintf("condId:%v rtype:%v params:%v", condId, rtype, p)) }(v.Id, v.Type, p) wg.Wait() } } go func() { for msg := range this.resultChan { // logrus.Debug("add msg") this.msgs = append(this.msgs, msg) // old := atomic.LoadInt32(&this.resultCount) // n := old - 1 // if atomic.CompareAndSwapInt32(&this.resultCount, old, n) { // break // } } }() go func() { var flag bool for !flag { count := atomic.LoadInt32(&this.resultCount) logrus.Debug("count:", count) if count == 100 { logrus.Debug("结束") record := strings.Join(this.msgs, "\n") var buf bytes.Buffer buf.WriteString(fmt.Sprintf("---任务参数测试报告---\n")) buf.WriteString(record) buf.WriteString("\n-------") file, err := os.OpenFile(filepath.Join(this.reportPath, "report.txt"), os.O_TRUNC|os.O_CREATE, os.ModePerm) if err != nil { logrus.Error(err) } defer file.Close() if _, err := file.WriteString(buf.String()); err != nil { logrus.Error(err) } flag = true } } }() } autoTestBtn := widget.NewButton("自动触发配置", func() { paiWin := dialog.NewCustom("自动触发配置", "关闭", autoTestForm, this.w) paiWin.Resize(fyne.NewSize(600, 300)) paiWin.Show() }) autoBtn := widget.NewButton("模拟API测试", func() { for k, v := range pb2.TaskCase { if k != "" && strings.Contains(k, ".") && v.Enabled { if err := service.GetPttService().SendToClient( v.MainType, v.SubType, v.Req, ); err != nil { logrus.Errorf("%v.%v err:%v", v.MainType, v.SubType, err) return } logrus.Debugf("%v.%v", v.MainType, v.SubType) } } }) this.rtestListener() c := container.NewBorder( container.NewHBox(testBtn, autoTestBtn, autoBtn), nil, nil, nil, this.itemList.ItemList) return c } func (this *RtaskTestView) loadProtocol() { for k, v := range pb2.TaskCase { if k != "" && strings.Contains(k, ".") && v.Enabled { item := common.Item{ Id: k, Text: fmt.Sprintf("%v (%v)", v.NavLabel, k), } this.itemList.AddItem(item) } } } func (this *RtaskTestView) rtestListener() { if this.flag { return } this.obs.AddListener(observer.EVENT_REQ_RSP, observer.Listener{ OnNotify: func(d interface{}, args ...interface{}) { data := d.(*pb.UserMessage) if data.MainType == string(comm.ModuleRtask) && data.SubType == "rtest" { rsp := &pb.RtaskTestResp{} if !comm.ProtoUnmarshal(data, rsp) { logrus.Error("unmarshal err") return } msg := fmt.Sprintf("%v - %v", rsp.RtaskType, rsp.Flag) this.resultChan <- msg atomic.AddInt32(&this.resultCount, 1) logrus.Debug("resp", msg) } }, }) this.flag = true }