You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
1272 lines
39 KiB
1272 lines
39 KiB
package service |
|
|
|
import ( |
|
"bytes" |
|
"context" |
|
"encoding/json" |
|
"html/template" |
|
"io" |
|
"net/url" |
|
"os" |
|
"regexp" |
|
"strconv" |
|
"strings" |
|
"time" |
|
|
|
"go-common/app/admin/ep/melloi/conf" |
|
"go-common/app/admin/ep/melloi/model" |
|
"go-common/library/ecode" |
|
"go-common/library/log" |
|
) |
|
|
|
//QueryScripts query scripts |
|
func (s *Service) QueryScripts(script *model.Script, pn, ps int) (scripts []*model.Script, err error) { |
|
if ps <= 0 || pn <= 0 { |
|
ps = 10 |
|
pn = 1 |
|
} |
|
if scripts, err = s.dao.QueryScripts(script, pn, ps); err != nil { |
|
log.Error("s.dao.QueryScripts error :(%v)", err) |
|
return |
|
} |
|
for _, script := range scripts { |
|
if script.APIHeader != "" { |
|
if err = json.Unmarshal([]byte(script.APIHeader), &script.Headers); err != nil { |
|
log.Error("get script header err : (%v), scriptId:(%d)", err, script.ID) |
|
} |
|
} |
|
if script.ArgumentString != "" { |
|
if err = json.Unmarshal([]byte(script.ArgumentString), &script.ArgumentsMap); err != nil { |
|
log.Error("get script argument err: (%v), scriptId:(%d)", err, script.ID) |
|
} |
|
} |
|
if script.OutputParams != "" { |
|
if err = json.Unmarshal([]byte(script.OutputParams), &script.OutputParamsMap); err != nil { |
|
log.Error("get script OutputParams err: (%v), scriptId:(%d)", err, script.ID) |
|
} |
|
} |
|
} |
|
return |
|
} |
|
|
|
//CountQueryScripts count query scripts |
|
func (s *Service) CountQueryScripts(script *model.Script) (total int) { |
|
return s.dao.CountQueryScripts(script) |
|
} |
|
|
|
//QueryScriptSnap query scriptSnap |
|
func (s *Service) QueryScriptSnap(scriptSnap *model.ScriptSnap) (snaps []*model.ScriptSnap, err error) { |
|
return s.dao.QueryScriptSnap(scriptSnap) |
|
} |
|
|
|
//QueryScriptsByPage query script by page |
|
func (s *Service) QueryScriptsByPage(c context.Context, sessionID string, qsrq *model.QueryScriptRequest) (rsp *model.QueryScriptResponse, err error) { |
|
// 获取服务树节点 |
|
var ( |
|
treeNodes []string |
|
treeNodesd []string |
|
) |
|
if treeNodesd, err = s.QueryUserRoleNode(c, sessionID); err != nil { |
|
log.Error("QueryUserRoleNode err (%v):", err) |
|
} |
|
treeNodes = append(treeNodesd, "") |
|
if ExistsInSlice(qsrq.Executor, conf.Conf.Melloi.Executor) { |
|
//rsp, err = s.dao.QueryScriptsByPageWhiteName(&qsrq.Script, qsrq.PageNum, qsrq.PageSize) |
|
if rsp, err = s.dao.QueryScriptsByPageWhiteName(&qsrq.Script, qsrq.PageNum, qsrq.PageSize); err != nil { |
|
return |
|
} |
|
} else { |
|
if rsp, err = s.dao.QueryScriptsByPage(&qsrq.Script, qsrq.PageNum, qsrq.PageSize, treeNodes); err != nil { |
|
return |
|
} |
|
} |
|
|
|
for _, script := range rsp.Scripts { |
|
if script.APIHeader != "" { |
|
if err = json.Unmarshal([]byte(script.APIHeader), &script.Headers); err != nil { |
|
log.Error("get script header err : (%v), scriptId:(%d)", err, script.ID) |
|
} |
|
} |
|
if script.ArgumentString != "" { |
|
if err = json.Unmarshal([]byte(script.ArgumentString), &script.ArgumentsMap); err != nil { |
|
log.Error("get script argument err: (%v), scriptId:(%d)", err, script.ID) |
|
} |
|
} |
|
if script.OutputParams != "" { |
|
if err = json.Unmarshal([]byte(script.OutputParams), &script.OutputParamsMap); err != nil { |
|
log.Error("get script OutputParams err: (%v), scriptId:(%d)", err, script.ID) |
|
} |
|
} |
|
} |
|
|
|
// 获取label |
|
for _, script := range rsp.Scripts { |
|
lr := model.LabelRelation{Type: model.ScriptType, TargetID: int64(script.ID)} |
|
if script.Labels, err = s.dao.QueryLabelRelation(&lr); err != nil { |
|
return |
|
} |
|
} |
|
return |
|
} |
|
|
|
//AddAndExcuScript add script and excute it |
|
func (s *Service) AddAndExcuScript(c context.Context, script *model.Script, cookie string, scene *model.Scene, fileWrite, convjson bool) (resp model.DoPtestResp, err error) { |
|
var ( |
|
scriptID int |
|
groupID int |
|
runOrder int |
|
testNameNick string |
|
message string |
|
scriptd model.Script |
|
paramList *model.ParamList |
|
isEdit = false |
|
) |
|
|
|
if message, scriptd, err = s.AddScript(script, fileWrite); err != nil { |
|
log.Error("sorry, addScript fail : (%v)", err) |
|
return |
|
} |
|
headerString := MapToString(scriptd.Headers) |
|
argumentString := MapToString(scriptd.ArgumentsMap) |
|
scriptd.ArgumentString = argumentString |
|
scriptd.APIHeader = headerString |
|
scriptd.OutputParams = MapToString(scriptd.OutputParamsMap) |
|
//场景压测中选择已有接口时,去修改默认的熔断成功率的值(新增接口时不修改) |
|
if scene.IsBatch { |
|
scriptd.Fusing = scene.Fusing |
|
} |
|
|
|
if convjson { |
|
scriptd.ArgumentString = script.ArgumentString |
|
scriptd.APIHeader = script.APIHeader |
|
scriptd.OutputParams = script.OutputParams |
|
} |
|
//场景压测独有的逻辑 |
|
if scriptd.TestType == model.SCENE_SCRIPT_TYPE { |
|
//根据接口参数依赖,计算出接口分组与执行顺序 |
|
if paramList, err = s.dao.QueryParams(&scriptd, scene); err != nil { |
|
log.Error("s.dao.QueryParams err :(%v)", err) |
|
return |
|
} |
|
scriptd.GroupID, scriptd.RunOrder = GroupOrder(isEdit, &scriptd, scene, paramList) |
|
} |
|
|
|
//非debug 执行的 循环次数为-1 即永久 |
|
if scriptd.Loops == -1 { |
|
if len(script.OutputParamsMap) == 0 || script.OutputParams == "[]" { |
|
scriptd.OutputParams = "[{\"\":\"\"}]" |
|
} |
|
if scriptID, groupID, runOrder, err = s.dao.AddScript(&scriptd); err != nil { |
|
log.Error("s.dao.AddScript err : (%v)", err) |
|
message = "sql excute err" |
|
return |
|
} |
|
} |
|
|
|
//如果不是复制脚本操作 或者 不是保存,则执行jmeter压测 |
|
if !script.IsCopy && !script.IsSave { |
|
tim := strconv.FormatInt(time.Now().Unix(), 10) |
|
testNameNick = scriptd.TestName + tim |
|
log.Info("开始调用压测job-------\n") |
|
ptestParam := model.DoPtestParam{ |
|
UserName: scriptd.UpdateBy, // 用户名 |
|
LoadTime: scriptd.LoadTime, //运行时间 |
|
TestNames: StringToSlice(scriptd.TestName), //接口名转数组 |
|
FileName: scriptd.SavePath, // jmx文件 |
|
ResJtl: scriptd.ResJtl, // jtl 文件 |
|
JmeterLog: scriptd.JmeterLog, // jmeterlog时间戳 |
|
Department: script.Department, |
|
Project: script.Project, |
|
APP: script.App, |
|
ScriptID: scriptID, |
|
IsDebug: script.IsDebug, //false |
|
Cookie: cookie, // 用不到 |
|
URL: scriptd.URL, // 微信通知URL |
|
LabelIDs: script.LabelIds, |
|
Domain: scriptd.Domain, |
|
FileSplit: script.FileSplit, // 文件切割 |
|
SplitNum: script.SplitNum, // 切割数量 |
|
Fusing: script.Fusing, |
|
APIHeader: scriptd.APIHeader, |
|
ExecuDockerSum: script.ExecuDockerSum, |
|
UseBusinessStop: script.UseBusinessStop, |
|
BusinessStopPercent: script.BusinessStopPercent, |
|
} |
|
if resp, err = s.DoPtestByJmeter(c, ptestParam, StringToSlice(testNameNick)); err != nil { |
|
log.Error("DoPtestByJmeter err :(%v)", err) |
|
message = "DoPtestByJmeter err " |
|
return |
|
} |
|
resp.Message = message |
|
} |
|
resp.ScriptID = scriptID |
|
resp.GroupID = groupID |
|
resp.RunOrder = runOrder |
|
return |
|
} |
|
|
|
//AddScript add script |
|
func (s *Service) AddScript(script *model.Script, fileWrite bool) (message string, scriptd model.Script, err error) { |
|
var ( |
|
buff *template.Template |
|
file *os.File |
|
scriptPath string |
|
u *url.URL |
|
sinfoJSON []byte |
|
JSON []byte |
|
JSONExtractors string |
|
dataFileName string |
|
Assertionsd []string |
|
) |
|
log.Info("threadsSum :(%d)", script.ThreadsSum) |
|
if script.LoadTime > s.c.Jmeter.TestTimeLimit { |
|
script.LoadTime = s.c.Jmeter.TestTimeLimit |
|
} |
|
//判断url |
|
if !strings.Contains(script.URL, "http://") && !strings.Contains(script.URL, "https://") { |
|
script.URL = "http://" + script.URL |
|
} |
|
if script.Delimiter == "" { |
|
script.Delimiter = "," |
|
} |
|
if u, err = url.Parse(script.URL); err != nil || u == nil { |
|
log.Error("sorry,url is not standard,error(%v)", err) |
|
err = ecode.MelloiUrlParseError |
|
return |
|
} |
|
if script.Data == "" { |
|
buff, err = template.ParseFiles(s.c.Jmeter.JmeterScUcodedTmp) |
|
} else { |
|
buff, err = template.ParseFiles(s.c.Jmeter.JmeterScTmp) |
|
} |
|
if err != nil { |
|
log.Error("open file failed! error %v", err) |
|
return |
|
} |
|
if script.Assertion != "" { |
|
script.UseAssertion = true |
|
Assertions := strings.Split(script.Assertion, "|") |
|
for _, assert := range Assertions { |
|
Assertionsd = append(Assertionsd, model.AssertionStart+assert+model.AssertionEnd) |
|
} |
|
script.AssertionString = unescaped(SliceToString(Assertionsd, " ")) |
|
} |
|
if len(script.OutputParamsMap) > 0 && script.OutputParams != "[{\"\":\"\"}]" && script.OutputParams != "[]" && script.OutputParams != "" { |
|
if JSONExtractors, err = s.SetJSONExtractors(script); err != nil { |
|
return |
|
} |
|
if JSONExtractors != "" { |
|
script.JSONExtractor = unescaped(JSONExtractors) |
|
} |
|
} |
|
|
|
// POST 请求的 binary 逻辑 |
|
if script.MultipartFile != "" && script.MultipartPath != "" { |
|
script.UseMultipart = true |
|
multiPartInfo := SetMultiPartInfo(script) |
|
script.MultiPartInfo = unescaped(multiPartInfo) |
|
} |
|
stringHeader := SetHeaders(script.Headers, script.ID) |
|
ArgmentStr := SetArguments(script.ArgumentsMap, script.ID) |
|
ArgmentString := unescaped(ArgmentStr) |
|
script.Arguments = ArgmentString |
|
stringHeaderd := unescaped(stringHeader) |
|
script.HeaderString = stringHeaderd |
|
script.ProcType = u.Scheme |
|
script.Domain = u.Hostname() |
|
script.Port = u.Port() |
|
if u.RawQuery == "" { |
|
script.Path = u.Path |
|
script.RowQuery = "appkey=" + conf.Conf.Melloi.AppkeyProd |
|
} else { |
|
script.Path = u.Path + "?" + u.RawQuery |
|
script.RowQuery = u.RawQuery + "&appkey=" + conf.Conf.Melloi.AppkeyProd |
|
} |
|
|
|
if script.UseSign { |
|
script.Path = u.Path + "?${params}" |
|
} |
|
dataFileName = script.FileName |
|
script.FileName = script.ScriptPath + script.FileName |
|
if script.ScriptPath != "" && script.FileName == "" && !script.Upload { |
|
message = "dataFile is not exists" |
|
log.Error(message) |
|
return |
|
} |
|
|
|
if script.Loops == 0 { |
|
script.Loops = -1 |
|
} |
|
//极速模式(线程NIO模式) |
|
if script.IsAsync { |
|
script.AsyncInfo = unescaped(model.AsyncInfo) |
|
} |
|
//生成压测脚本 |
|
if sinfoJSON, err = json.Marshal(script); err != nil { |
|
log.Error("script err (%v):", err) |
|
return |
|
} |
|
sc := string(sinfoJSON) |
|
log.Info("script :(%s)", sc) |
|
//判断是否使用内置参数 |
|
if strings.Contains(sc, "${mid}") || strings.Contains(sc, "${access_key}") || script.UseSign { |
|
script.UseBuiltinParam = true |
|
} |
|
//fileWrite = true ,需要创建文件,为 false ,不需要创建文件 |
|
if fileWrite { |
|
//创建脚本保存路径 |
|
if script.ScriptPath == "" { |
|
if scriptPath, err = s.uniqueFolderPath(script.SavePath); err != nil { |
|
return |
|
} |
|
} else { |
|
scriptPath = script.ScriptPath |
|
} |
|
SavePath := scriptPath + script.TestName + "/" |
|
log.Info("SavePath****: " + SavePath) |
|
if err = os.MkdirAll(SavePath, 0755); err != nil { |
|
log.Error("Create SavePath Err :(%v)", err) |
|
return |
|
} |
|
///创建脚本保存路径 脚本存放路径:部门/项目/应用/项目名/,须判断路径是否包含.jmx |
|
if !strings.Contains(script.SavePath, ".jmx") { |
|
// 创建脚本文件 部门/项目/应用/项目名/**.jmx |
|
if file, err = os.Create(SavePath + script.TestName + ".jmx"); err != nil { |
|
log.Error("create file error :(%v)", err) |
|
message = "create .jmx error" |
|
return |
|
} |
|
defer file.Close() |
|
//jtl 路径 |
|
script.ResJtl = SavePath + script.TestName + ".jtl" |
|
//jmeter-log 路径 |
|
script.JmeterLog = SavePath + script.TestName + ".log" |
|
|
|
} else { |
|
// 如果路径钟包含 .jmx ,则直接根据路径创建 |
|
if file, err = os.Create(script.SavePath); err != nil { |
|
log.Error("create file error :(%v)", err) |
|
message = "create .jmx error" |
|
return |
|
} |
|
defer file.Close() |
|
} |
|
buff = buff.Funcs(template.FuncMap{"unescaped": unescaped}) |
|
buff.Execute(io.Writer(file), script) |
|
script.SavePath = file.Name() |
|
} |
|
script.Ctime = time.Now() |
|
script.ProjectName = script.TestName |
|
if JSON, err = json.Marshal(script); err != nil { |
|
return |
|
} |
|
if err = json.Unmarshal([]byte(JSON), &scriptd); err != nil { |
|
log.Error("sorry,scriptd err(%v)", err) |
|
return |
|
} |
|
scriptd.HeaderString = stringHeaderd |
|
scriptd.Arguments = ArgmentString |
|
scriptd.JSONExtractor = script.JSONExtractor |
|
scriptd.Data = script.Data |
|
scriptd.FileName = dataFileName |
|
if script.FileName == "" || script.ParamsName == "" { |
|
scriptd.UseDataFile = false |
|
} else { |
|
scriptd.UseDataFile = true |
|
} |
|
|
|
if len(Assertionsd) > 0 { |
|
scriptd.AssertionString = unescaped(SliceToString(Assertionsd, " ")) |
|
} |
|
return |
|
} |
|
|
|
//DelScript sel script |
|
func (s *Service) DelScript(id int) error { |
|
return s.dao.DelScript(id) |
|
} |
|
|
|
//UpdateScript update script info |
|
func (s *Service) UpdateScript(script *model.Script) (updateResult string, err error) { |
|
var ( |
|
buff *template.Template |
|
stringHeader string |
|
Headers []map[string]string |
|
stringArgument string |
|
Arguments []map[string]string |
|
scriptd *model.Script |
|
u *url.URL |
|
file *os.File |
|
sinfoJSON []byte |
|
sinfoJSONd []byte |
|
JSONExtractors string |
|
Assertionsd []string |
|
) |
|
if scriptd, err = s.dao.QueryScriptByID(script.ID); err != nil { |
|
log.Error("query script fail , error %v", err) |
|
return |
|
} |
|
if script.Data == "" { |
|
buff, err = template.ParseFiles(s.c.Jmeter.JmeterScUcodedTmp) |
|
} else { |
|
buff, err = template.ParseFiles(s.c.Jmeter.JmeterScTmp) |
|
} |
|
if err != nil { |
|
log.Error("open file failed! error %v", err) |
|
return |
|
} |
|
if u, err = url.Parse(script.URL); err != nil || u == nil { |
|
log.Error("sorry,url is not standard,error(%v)", err) |
|
err = ecode.MelloiUrlParseError |
|
return |
|
} |
|
// 修改laodTime 和 threadsSum |
|
// ThreadGroup.ramp_time">{{.ReadyTime}}</stringProp> |
|
if file, err = os.Create(scriptd.SavePath); err != nil { |
|
log.Error("create file failed! error %v", err) |
|
return |
|
} |
|
defer file.Close() |
|
if err = json.Unmarshal([]byte(scriptd.APIHeader), &Headers); err != nil { |
|
updateResult = " scriptd.APIHeade json 不合法" |
|
log.Error("scriptd.APIHeader switch map failed! error %v", err) |
|
return |
|
} |
|
|
|
if err = json.Unmarshal([]byte(scriptd.ArgumentString), &Arguments); err != nil { |
|
updateResult = "scriptd.ArgumentString json 不合法" |
|
log.Error("scriptd.ArgumentString switch map failed! error %v", err) |
|
return |
|
} |
|
if len(scriptd.OutputParamsMap) > 0 && scriptd.OutputParams != "" && scriptd.OutputParams != "[{\"\":\"\"}]" && scriptd.OutputParams != "[]" { |
|
if err = json.Unmarshal([]byte(scriptd.OutputParams), &scriptd.OutputParamsMap); err != nil { |
|
log.Error("scriptd.OutputParams switch map failed! error %v", err) |
|
return |
|
} |
|
} |
|
stringHeader = SetHeaders(Headers, scriptd.ID) |
|
stringArgument = SetArguments(Arguments, scriptd.ID) |
|
if len(scriptd.OutputParamsMap) > 0 && scriptd.OutputParams != "[{\"\":\"\"}]" && scriptd.OutputParams != "[]" && script.OutputParams != "" { |
|
if JSONExtractors, err = s.SetJSONExtractors(scriptd); err != nil { |
|
return |
|
} |
|
if JSONExtractors != "" { |
|
script.JSONExtractor = unescaped(JSONExtractors) |
|
} |
|
} |
|
scriptd.HeaderString = unescaped(stringHeader) |
|
scriptd.Arguments = unescaped(stringArgument) |
|
scriptd.Data = script.Data |
|
scriptd.Assertion = script.Assertion |
|
scriptd.ReadyTime = script.ReadyTime |
|
scriptd.ThreadsSum = script.ThreadsSum |
|
scriptd.LoadTime = script.LoadTime |
|
scriptd.ProcType = u.Scheme |
|
scriptd.Domain = u.Hostname() |
|
scriptd.Port = u.Port() |
|
scriptd.TestName = script.TestName |
|
scriptd.FileName = scriptd.ScriptPath + scriptd.FileName |
|
if scriptd.Assertion != "" { |
|
scriptd.UseAssertion = true |
|
Assertions := strings.Split(scriptd.Assertion, "|") |
|
for _, assert := range Assertions { |
|
Assertionsd = append(Assertionsd, model.AssertionStart+assert+model.AssertionEnd) |
|
} |
|
scriptd.AssertionString = unescaped(SliceToString(Assertionsd, " ")) |
|
} |
|
|
|
//判断是否使用内置参数 |
|
if sinfoJSON, err = json.Marshal(script); err != nil { |
|
log.Error("script err :(%s)", err) |
|
return |
|
} |
|
if sinfoJSONd, err = json.Marshal(scriptd); err != nil { |
|
log.Error("script err :(%s)", err) |
|
return |
|
} |
|
sc := string(sinfoJSON) + string(sinfoJSONd) |
|
if strings.Contains(sc, "${mid}") || strings.Contains(sc, "${access_key}") || script.UseSign { |
|
scriptd.UseBuiltinParam = true |
|
} |
|
if u.RawQuery == "" { |
|
scriptd.Path = u.Path |
|
scriptd.RowQuery = "appkey=" + conf.Conf.Melloi.AppkeyProd |
|
} else { |
|
scriptd.Path = u.Path + "?" + u.RawQuery |
|
scriptd.RowQuery = u.RawQuery + "&appkey=" + conf.Conf.Melloi.AppkeyProd |
|
} |
|
if scriptd.UseSign { |
|
scriptd.Path = u.Path + "?${params}" |
|
} |
|
// POST 请求的 binary 逻辑 |
|
if scriptd.MultipartFile != "" && scriptd.MultipartPath != "" { |
|
scriptd.UseMultipart = true |
|
multiPartInfo := SetMultiPartInfo(scriptd) |
|
scriptd.MultiPartInfo = unescaped(multiPartInfo) |
|
} |
|
if scriptd.IsAsync { |
|
scriptd.AsyncInfo = unescaped(model.AsyncInfo) |
|
} |
|
buff = buff.Funcs(template.FuncMap{"unescaped": unescaped}) |
|
buff.Execute(io.Writer(file), scriptd) |
|
script.ProjectName = script.TestName |
|
script.KeepAlive = scriptd.KeepAlive |
|
if err = s.dao.UpdateScriptPart(script); err != nil { |
|
log.Error("s.dao.UpdateScript err :(%v)", err) |
|
return |
|
} |
|
updateResult = "success" |
|
return |
|
} |
|
|
|
//UpdateScriptAll update script all |
|
func (s *Service) UpdateScriptAll(script *model.Script, scene *model.Scene) (updateResult string, err error) { |
|
var ( |
|
scriptd model.Script |
|
paramList *model.ParamList |
|
isEdit = true |
|
groupId int |
|
runOrder int |
|
fileWrite bool |
|
) |
|
id := script.ID |
|
script.ID = 0 |
|
// script test_type 为1 表示 http 脚本 |
|
if script.TestType == model.HTTP_SCRIPT_TYPE { |
|
fileWrite = true |
|
} |
|
if _, scriptd, err = s.AddScript(script, fileWrite); err != nil { |
|
log.Error("sorry, addScript fail : (%v)", err) |
|
return |
|
} |
|
|
|
if script.TestType == model.SCENE_SCRIPT_TYPE { |
|
//根据接口参数依赖,计算出接口分组与执行顺序 |
|
if paramList, err = s.dao.QueryParams(&scriptd, scene); err != nil { |
|
log.Error("s.dao.QueryParams err :(%v)", err) |
|
return |
|
} |
|
groupId, runOrder = GroupOrderByEdit(isEdit, id, &scriptd, scene, paramList) |
|
if groupId != 0 && runOrder != 0 { |
|
scriptd.GroupID = groupId |
|
scriptd.RunOrder = runOrder |
|
} |
|
} |
|
|
|
scriptd.ID = id |
|
scriptd.SavePath = "" |
|
|
|
if scriptd.Loops == -1 { |
|
headerString := MapToString(scriptd.Headers) |
|
argumentString := MapToString(scriptd.ArgumentsMap) |
|
scriptd.OutputParams = MapToString(scriptd.OutputParamsMap) |
|
scriptd.ArgumentString = argumentString |
|
scriptd.APIHeader = headerString |
|
if err = s.dao.UpdateScript(&scriptd); err != nil { |
|
log.Error("s.dao.UpdateScript err : (%v)", err) |
|
return |
|
} |
|
} |
|
updateResult = "success" |
|
return |
|
} |
|
|
|
//AddJmeterSample add jmeter sample |
|
func (s *Service) AddJmeterSample(script *model.Script) (result string, err error) { |
|
var ( |
|
buff *template.Template |
|
u *url.URL |
|
b = bytes.NewBuffer(nil) |
|
JSONExtractors string |
|
Assertionsd []string |
|
) |
|
|
|
if script.Data == "" { |
|
buff, err = template.ParseFiles(s.c.Jmeter.JmeterSampleTmp) |
|
} else { |
|
buff, err = template.ParseFiles(s.c.Jmeter.JmeterSamplePostTmp) |
|
} |
|
if err != nil { |
|
log.Info("open template failed! (%v)", err) |
|
return |
|
} |
|
//判断url |
|
if !strings.Contains(script.URL, "http://") && !strings.Contains(script.URL, "https://") { |
|
script.URL = "http://" + script.URL |
|
} |
|
if script.Delimiter == "" { |
|
script.Delimiter = "," |
|
} |
|
if u, err = url.Parse(script.URL); err != nil || u == nil { |
|
log.Error("sorry,url is not standard,error(%v)", err) |
|
err = ecode.MelloiUrlParseError |
|
return |
|
} |
|
stringHeader := SetHeaders(script.Headers, script.ID) |
|
ArgmentStr := SetArguments(script.ArgumentsMap, script.ID) |
|
ArgmentString := unescaped(ArgmentStr) |
|
if len(script.OutputParamsMap) > 0 && script.OutputParams != "[{\"\":\"\"}]" && script.OutputParams != "[]" && script.OutputParams != "" { |
|
if JSONExtractors, err = s.SetJSONExtractors(script); err != nil { |
|
return |
|
} |
|
if JSONExtractors != "" { |
|
script.JSONExtractor = unescaped(JSONExtractors) |
|
} |
|
} |
|
script.Arguments = ArgmentString |
|
stringHeaderd := unescaped(stringHeader) |
|
script.HeaderString = stringHeaderd |
|
script.ProcType = u.Scheme |
|
script.Domain = u.Hostname() |
|
script.Port = u.Port() |
|
script.FileName = script.ScriptPath + script.FileName |
|
if u.RawQuery == "" { |
|
script.Path = u.Path |
|
script.RowQuery = "appkey=" + conf.Conf.Melloi.AppkeyProd |
|
} else { |
|
script.Path = u.Path + "?" + u.RawQuery |
|
script.RowQuery = u.RawQuery + "&appkey=" + conf.Conf.Melloi.AppkeyProd |
|
} |
|
if script.UseSign { |
|
script.Path = u.Path + "?${params}" |
|
} |
|
if script.Assertion != "" { |
|
script.UseAssertion = true |
|
Assertions := strings.Split(script.Assertion, "|") |
|
for _, assert := range Assertions { |
|
Assertionsd = append(Assertionsd, model.AssertionStart+assert+model.AssertionEnd) |
|
} |
|
script.AssertionString = unescaped(SliceToString(Assertionsd, " ")) |
|
} |
|
if script.ConstTimer > 0 && script.RandomTimer == 0 { |
|
constTimer := strings.Replace(model.ConstTimer, "1000", strconv.Itoa(script.ConstTimer), -1) |
|
script.ConstTimerInfo = unescaped(constTimer) |
|
} |
|
if script.ConstTimer > 0 && script.RandomTimer > 0 { |
|
constTimerd := strings.Replace(model.RandomTimer, "1000", strconv.Itoa(script.ConstTimer), -1) |
|
randomTimerd := strings.Replace(constTimerd, "500", strconv.Itoa(script.RandomTimer), -1) |
|
script.RandomTimerInfo = unescaped(randomTimerd) |
|
} |
|
buff = buff.Funcs(template.FuncMap{"unescaped": unescaped}) |
|
buff.Execute(b, script) |
|
result = b.String() |
|
return |
|
} |
|
|
|
//AddThreadGroup add thread group |
|
func (s *Service) AddThreadGroup(script *model.Script, sceneType int) (result string, err error) { |
|
var ( |
|
buff *template.Template |
|
scriptd model.Script |
|
b = bytes.NewBuffer(nil) |
|
) |
|
|
|
if _, scriptd, err = s.AddScript(script, false); err != nil { |
|
log.Error("s.AddScript err :(%v)", err) |
|
return |
|
} |
|
//并行get |
|
if sceneType == 1 && script.Data == "" { |
|
buff, err = template.ParseFiles(s.c.Jmeter.JmeterThGroupTmp) |
|
} |
|
|
|
//并行post |
|
if sceneType == 1 && script.Data != "" { |
|
buff, err = template.ParseFiles(s.c.Jmeter.JmeterThGroupPostTmp) |
|
} |
|
|
|
//串行get |
|
if sceneType == 2 && script.Data == "" { |
|
buff, err = template.ParseFiles(s.c.Jmeter.JmeterThGroupDuliTmp) |
|
} |
|
|
|
//串行 post |
|
if sceneType == 2 && script.Data != "" { |
|
buff, err = template.ParseFiles(s.c.Jmeter.JmeterThGroupPostDuliTmp) |
|
} |
|
|
|
if err != nil { |
|
log.Info("open template failed! (%v)", err) |
|
return |
|
} |
|
buff = buff.Funcs(template.FuncMap{"unescaped": unescaped}) |
|
scriptd.FileName = scriptd.ScriptPath + scriptd.FileName |
|
buff.Execute(b, scriptd) |
|
result = b.String() |
|
return |
|
} |
|
|
|
//GetThreadGroup get thread group |
|
func (s *Service) GetThreadGroup(scrThreadGroup model.ScrThreadGroup) (threadGroup string, err error) { |
|
var ( |
|
threadGroups []string |
|
IsSerial bool |
|
groups []int |
|
groupMap = make(map[int]int) |
|
RunOrders []int |
|
scriptsd []*model.Script |
|
scriptsds [][]*model.Script |
|
threadGroupd string |
|
threadGroupds []string |
|
threadSamples []string |
|
threadSample string |
|
threadSamplesd string |
|
threadGrou string |
|
) |
|
for _, script := range scrThreadGroup.Scripts { |
|
RunOrders = append(RunOrders, script.RunOrder) |
|
groupMap[script.GroupID]++ |
|
if script.APIHeader != "" && script.APIHeader != "[{\"\":\"\"}]" { |
|
if err = json.Unmarshal([]byte(script.APIHeader), &script.Headers); err != nil { |
|
log.Error("get script header err : (%v), scriptId:(%d)", err, script.ID) |
|
} |
|
} |
|
if script.ArgumentString != "" && script.ArgumentString != "[{\"\":\"\"}]" { |
|
if err = json.Unmarshal([]byte(script.ArgumentString), &script.ArgumentsMap); err != nil { |
|
log.Error("get script argument err: (%v), scriptId:(%d)", err, script.ID) |
|
} |
|
} |
|
if script.OutputParams != "" && script.OutputParams != "[{\"\":\"\"}]" && script.OutputParams != "[]" { |
|
if err = json.Unmarshal([]byte(script.OutputParams), &script.OutputParamsMap); err != nil { |
|
log.Error("get script OutputParams err: (%v), scriptId:(%d)", err, script.ID) |
|
} |
|
} |
|
} |
|
for _, order := range RunOrders { |
|
if order > 1 { |
|
IsSerial = true |
|
break |
|
} |
|
} |
|
for k := range groupMap { |
|
groups = append(groups, k) |
|
} |
|
//并行脚本逻辑 |
|
if !IsSerial { |
|
for _, script := range scrThreadGroup.Scripts { |
|
if threadGrou, err = s.AddThreadGroup(script, 1); err != nil { |
|
log.Error("d.GetThroupGroupJmeter: error(%v)", err) |
|
return |
|
} |
|
threadGroups = append(threadGroups, threadGrou) |
|
} |
|
for _, thgroup := range threadGroups { |
|
threadGroupd = threadGroupd + thgroup |
|
} |
|
threadGroup = threadGroupd |
|
return |
|
} |
|
|
|
//串行脚本逻辑 |
|
for _, group := range groups { |
|
for i := 0; i < len(scrThreadGroup.Scripts); i++ { |
|
if scrThreadGroup.Scripts[i].GroupID == group { |
|
scriptsd = append(scriptsd, scrThreadGroup.Scripts[i]) |
|
} |
|
} |
|
scriptsds = append(scriptsds, scriptsd) |
|
scriptsd = []*model.Script{} |
|
} |
|
|
|
// 每个线程组内的接口,按照接口的 RunOrder 属性进行排序 |
|
for _, scriptsd := range scriptsds { |
|
for i := 0; i < len(scriptsd)-1; i++ { |
|
for j := i + 1; j < len(scriptsd); j++ { |
|
if scriptsd[i].RunOrder > scriptsd[j].RunOrder { |
|
tmp := scriptsd[i] |
|
scriptsd[i] = scriptsd[j] |
|
scriptsd[j] = tmp |
|
} |
|
} |
|
} |
|
} |
|
|
|
for k := 0; k < len(scriptsds); k++ { |
|
if len(scriptsds[k]) == 1 { |
|
if threadGroupd, err = s.AddThreadGroup(scriptsds[k][0], 1); err != nil { |
|
log.Error("d.GetThroupGroupJmeter: error(%v)", err) |
|
return |
|
} |
|
} else { |
|
//生成一个线程组,再往线程组插入 sample |
|
if threadGroupd, err = s.AddThreadGroup(scriptsds[k][0], 2); err != nil { |
|
log.Error(" s.AddScript err :(%v)", err) |
|
return |
|
} |
|
for i := 0; i < len(scriptsds[k]); i++ { |
|
//从第二个接口开始生成 sample |
|
if i > 0 { |
|
if threadSample, err = s.AddJmeterSample(scriptsds[k][i]); err != nil { |
|
log.Error("s.dao.GetThroupSeriesSample err :(%v)", err) |
|
return |
|
} |
|
threadSamples = append(threadSamples, threadSample) |
|
} |
|
} |
|
} |
|
for j := 0; j < len(threadSamples); j++ { |
|
threadSamplesd = threadSamplesd + threadSamples[j] |
|
} |
|
//生成一个 线程组 |
|
threadGroupM := strings.Replace(threadGroupd, "+-+-+*", threadSamplesd, -1) |
|
|
|
//多个线程组 |
|
threadGroupds = append(threadGroupds, threadGroupM) |
|
threadSamples = []string{} |
|
threadSamplesd = "" |
|
} |
|
|
|
for _, threadGrou := range threadGroupds { |
|
threadGroup = threadGroup + threadGrou |
|
} |
|
return |
|
} |
|
|
|
//URLCheck url check |
|
func (s *Service) URLCheck(script *model.Script) (urlEncode *model.URLEncode, err error) { |
|
var ( |
|
tempUrl *url.URL |
|
) |
|
urlEncode = &model.URLEncode{} |
|
if strings.Contains(script.URL, "?") { |
|
if tempUrl, err = url.Parse(script.URL); err != nil { |
|
return |
|
} |
|
params := tempUrl.RawQuery |
|
paramList := strings.Split(params, "&") |
|
for _, param := range paramList { |
|
value := strings.Split(param, "=")[1] |
|
var myMap map[string]interface{} |
|
if err = json.Unmarshal([]byte(value), &myMap); err != nil { |
|
urlEncode.ParamsType = "nojson" |
|
urlEncode.NewUrl = script.URL |
|
continue |
|
} |
|
urlEncode.ParamsType = "json" |
|
newParams := tempUrl.Query().Encode() |
|
urlEncode.NewUrl = strings.Split(script.URL, "?")[0] + "?" + newParams |
|
return |
|
} |
|
} |
|
return |
|
} |
|
|
|
//AddTimer add Timer |
|
func (s *Service) AddTimer(script *model.Script) error { |
|
return s.dao.AddScriptTimer(script) |
|
} |
|
|
|
//SetHeaders set headers |
|
func SetHeaders(Headers []map[string]string, scriptId int) (stringHeader string) { |
|
var ( |
|
stringHeaders []string |
|
HeaderString string |
|
) |
|
|
|
// 表示直接生成的脚本,非修改 |
|
if scriptId == 0 { |
|
for _, header := range Headers { |
|
k := header["key"] |
|
v := header["value"] |
|
HeaderString = model.HeaderStart + k + model.HeaderMid + v + model.HeaderEnd |
|
stringHeaders = append(stringHeaders, HeaderString) |
|
} |
|
} else { |
|
//修改脚本,header 从数据库取出的 |
|
for _, header := range Headers { |
|
for k, v := range header { |
|
HeaderString = model.HeaderStart + k + model.HeaderMid + v + model.HeaderEnd |
|
stringHeaders = append(stringHeaders, HeaderString) |
|
} |
|
} |
|
} |
|
|
|
for _, str := range stringHeaders { |
|
stringHeader = stringHeader + str + "\r\n" |
|
} |
|
return |
|
} |
|
|
|
//SetArguments set argument |
|
func SetArguments(Arguments []map[string]string, scriptId int) (stringArgument string) { |
|
var ( |
|
stringArguments []string |
|
ArgumentString string |
|
) |
|
|
|
// 表示直接生成的脚本,非修改 |
|
if scriptId == 0 { |
|
for _, argument := range Arguments { |
|
k := argument["key"] |
|
v := argument["value"] |
|
ArgumentString = model.ElementPropName + k + model.HTTPArgument + model.HTTPArgumentEncode + model.ArgumentStart + v + model.ArgumentMid + k + model.ArgumentEnd |
|
stringArguments = append(stringArguments, ArgumentString) |
|
} |
|
} else { |
|
//修改脚本,argument 从数据库取出的 |
|
for _, argument := range Arguments { |
|
for k, v := range argument { |
|
ArgumentString = model.ElementPropName + k + model.HTTPArgument + model.HTTPArgumentEncode + model.ArgumentStart + v + model.ArgumentMid + k + model.ArgumentEnd |
|
stringArguments = append(stringArguments, ArgumentString) |
|
} |
|
} |
|
} |
|
|
|
for _, str := range stringArguments { |
|
stringArgument = stringArgument + str + "\r\n" |
|
} |
|
return |
|
} |
|
|
|
//SetJSONExtractor set JSONExtractorgo |
|
func (s *Service) SetJSONExtractor(jsonExt model.JSONExtractor) (JSONExtractor string, err error) { |
|
var ( |
|
buff *template.Template |
|
b = bytes.NewBuffer(nil) |
|
) |
|
buff, err = template.ParseFiles(s.c.Jmeter.JSONExtractorTmp) |
|
if err != nil { |
|
log.Info("open template failed! (%v)", err) |
|
return |
|
} |
|
buff = buff.Funcs(template.FuncMap{"unescaped": unescaped}) |
|
buff.Execute(b, jsonExt) |
|
JSONExtractor = b.String() |
|
return |
|
} |
|
|
|
//SetJSONExtractors Set JSONExtractors |
|
func (s *Service) SetJSONExtractors(script *model.Script) (JSONExtractors string, err error) { |
|
var ( |
|
JSONExtractords []string |
|
jsonExt model.JSONExtractor |
|
JSONExtractord string |
|
) |
|
// 表示直接生成的脚本,非修改 |
|
if script.ID == 0 { |
|
for _, OutputParam := range script.OutputParamsMap { |
|
jsonExt.JSONName = OutputParam["key"] |
|
jsonExt.JSONPath = OutputParam["value"] |
|
if jsonExt.JSONName != "" && jsonExt.JSONPath != "" { |
|
if JSONExtractord, err = s.SetJSONExtractor(jsonExt); err != nil { |
|
log.Error("SetJSONExtractor err :(%v) ", err) |
|
return |
|
} |
|
JSONExtractords = append(JSONExtractords, JSONExtractord) |
|
} |
|
} |
|
} else { |
|
//修改脚本,header 从数据库取出的 |
|
for _, OutputParam := range script.OutputParamsMap { |
|
for k, v := range OutputParam { |
|
jsonExt.JSONName = k |
|
jsonExt.JSONPath = v |
|
} |
|
if jsonExt.JSONName != "" && jsonExt.JSONPath != "" { |
|
if JSONExtractord, err = s.SetJSONExtractor(jsonExt); err != nil { |
|
log.Error("SetJSONExtractor err :(%v) ", err) |
|
return |
|
} |
|
JSONExtractords = append(JSONExtractords, JSONExtractord) |
|
} |
|
} |
|
} |
|
JSONExtractors = SliceToString(JSONExtractords, " ") |
|
return |
|
} |
|
|
|
//SetMultiPartInfo Set MultiPartInfo |
|
func SetMultiPartInfo(script *model.Script) (multiPartInfo string) { |
|
multiPartInfo = model.MultipartName + script.MultipartPath + script.MultipartFile + model.MultipartFilePath + |
|
script.MultipartPath + script.MultipartFile + model.MultipartFilePathd + script.MultipartParam + |
|
model.MultipartMimetype + script.MimeType + model.MultipartEnd |
|
return |
|
} |
|
|
|
//MapToString map to string |
|
func MapToString(strMapArr []map[string]string) (headerString string) { |
|
for _, strMap := range strMapArr { |
|
k, keyOk := strMap["key"] |
|
v, valueOK := strMap["value"] |
|
if keyOk != valueOK { |
|
return |
|
} |
|
if keyOk { |
|
delete(strMap, "key") |
|
delete(strMap, "value") |
|
strMap[k] = v |
|
} |
|
} |
|
headers, _ := json.Marshal(strMapArr) |
|
headerString = string(headers) |
|
return |
|
} |
|
|
|
//StringToMap string to map |
|
func StringToMap(headerString string) (mapHeaders []map[string]string) { |
|
if headerString != "[{\"\":\"\"}]" { |
|
if err := json.Unmarshal([]byte(headerString), &mapHeaders); err != nil { |
|
return |
|
} |
|
} |
|
return |
|
} |
|
|
|
func unescaped(x string) interface{} { |
|
return template.HTML(x) |
|
} |
|
|
|
//HostInfo add hostinfo |
|
func HostInfo(domain string, apiHeader string) (hostInfo string) { |
|
mapHeaders := StringToMap(apiHeader) |
|
reg := regexp.MustCompile(`.com|.co`) |
|
strs := reg.FindAllString(domain, -1) |
|
if len(strs) != 0 { |
|
for _, str := range strs { |
|
if (strings.Contains(str, ".com") || strings.Contains(str, ".co")) && strings.Contains(apiHeader, domain) { //绑定至用户指定的ip |
|
for _, header := range mapHeaders { |
|
for host := range header { |
|
conf.Conf.Paas.HostInfo = domain + ":" + host |
|
hostInfo = conf.Conf.Paas.HostInfo |
|
} |
|
} |
|
} else if strings.Contains(str, ".com") || strings.Contains(str, ".co") { //默认绑定至172.22.22.222 |
|
conf.Conf.Paas.HostInfo = domain + ":" + conf.Conf.Melloi.DefaultHost |
|
hostInfo = conf.Conf.Paas.HostInfo |
|
} |
|
} |
|
} |
|
return |
|
} |
|
|
|
//HostInfoList add hostinfo list |
|
func HostInfoList(scripts []*model.Script) (hostInfo string) { |
|
for _, script := range scripts { |
|
mapHeaders := StringToMap(script.APIHeader) |
|
reg := regexp.MustCompile(`.com|.co`) |
|
strs := reg.FindAllString(script.Domain, -1) |
|
if len(strs) != 0 { |
|
for _, str := range strs { |
|
if (strings.Contains(str, ".com") || strings.Contains(str, ".co")) && strings.Contains(script.APIHeader, script.Domain) { //绑定至用户指定的ip |
|
for _, header := range mapHeaders { |
|
for host := range header { |
|
conf.Conf.Paas.HostInfo = script.Domain + ":" + host |
|
hostInfo = conf.Conf.Paas.HostInfo |
|
} |
|
} |
|
} else if strings.Contains(str, ".com") || strings.Contains(str, ".co") { //默认绑定至172.22.22.222 |
|
hostInfo = hostInfo + script.Domain + ":" + conf.Conf.Melloi.DefaultHost + "," |
|
} |
|
} |
|
} |
|
} |
|
conf.Conf.Paas.HostInfo = hostInfo |
|
return |
|
} |
|
|
|
//HostInfoByUploadSc host info By UploadSc |
|
func HostInfoByUploadSc(domain string) (hostInfo string) { |
|
domains := strings.Split(domain, ",") |
|
for _, dom := range domains { |
|
hostInfo = hostInfo + dom + ":" + conf.Conf.Melloi.DefaultHost + "," |
|
} |
|
conf.Conf.Paas.HostInfo = hostInfo |
|
return |
|
} |
|
|
|
// GroupOrder Group Order |
|
func GroupOrder(isEdit bool, script *model.Script, scene *model.Scene, paramList *model.ParamList) (groupId int, runOrder int) { |
|
var ( |
|
flag = 0 |
|
//tmpIndex = 0 |
|
u *url.URL |
|
err error |
|
) |
|
if u, err = url.Parse(script.URL); err != nil || u == nil { |
|
log.Error("sorry, url is wrong, please check. error(%v)", err) |
|
err = ecode.MelloiUrlParseError |
|
return |
|
} |
|
if len(paramList.ParamList) > 0 { |
|
for _, paramList := range paramList.ParamList { |
|
tempList := strings.Split(u.RawQuery, "&") |
|
tempHeaderList := strings.Split(script.APIHeader, ",") |
|
tempArgumentList := strings.Split(script.ArgumentString, ",") |
|
tempDataList := strings.Split(script.Data, ",") |
|
if u.RawQuery == "" && (script.APIHeader == "[{\"\":\"\"}]" || script.APIHeader == "[]") && script.Data == "" && (script.ArgumentString == "[{\"\":\"\"}]" || script.ArgumentString == "[]") { |
|
if scene.SceneType == 1 || scene.SceneType == 0 { |
|
groupId = paramList.GroupID + 1 |
|
runOrder = 1 |
|
continue |
|
} else if scene.SceneType == 2 { |
|
groupId = paramList.GroupID |
|
runOrder = paramList.RunOrder + 1 |
|
continue |
|
} |
|
} |
|
//url params check |
|
if u.RawQuery != "" { |
|
if groupId, runOrder, flag, err = OrderEach(isEdit, tempList, paramList, scene.SceneType); err != nil || (runOrder != 1 && flag == 0) { |
|
return |
|
//} else if flag == 2 { |
|
// tmpIndex = index |
|
// break |
|
} |
|
} |
|
//APIHeader params check |
|
if script.APIHeader != "[{\"\":\"\"}]" && script.APIHeader != "[]" { |
|
if groupId, runOrder, flag, err = OrderEach(isEdit, tempHeaderList, paramList, scene.SceneType); err != nil || (runOrder != 1 && flag == 0) { |
|
return |
|
} |
|
} |
|
//ArgumentString params check |
|
if script.ArgumentString != "[{\"\":\"\"}]" && script.ArgumentString != "[]" { |
|
if groupId, runOrder, flag, err = OrderEach(isEdit, tempArgumentList, paramList, scene.SceneType); err != nil || (runOrder != 1 && flag == 0) { |
|
return |
|
} |
|
} |
|
//body params check |
|
if script.Data != "" { |
|
if groupId, runOrder, flag, err = OrderEach(isEdit, tempDataList, paramList, scene.SceneType); err != nil || (runOrder != 1 && flag == 0) { |
|
return |
|
} |
|
} |
|
} |
|
//for i := tmpIndex; i < len(paramList.ParamList); i++ { |
|
// if err = s.dao.UpdateRunOrder(paramList.ParamList[i].); err != nil { |
|
// log.Error("s.dao.UpdateScript err :(%v)", err) |
|
// return |
|
// } |
|
//} |
|
} else if script.GroupID != 0 { |
|
groupId = script.GroupID |
|
runOrder = 1 |
|
} else { |
|
groupId = 1 |
|
runOrder = 1 |
|
} |
|
return |
|
} |
|
|
|
// GroupOrderByEdit Group Order By Edit |
|
func GroupOrderByEdit(isEdit bool, id int, script *model.Script, scene *model.Scene, paramList *model.ParamList) (groupId int, runOrder int) { |
|
var ( |
|
flag = 0 |
|
//tmpIndex = 0 |
|
u *url.URL |
|
err error |
|
) |
|
if u, err = url.Parse(script.URL); err != nil || u == nil { |
|
log.Error("sorry, url is wrong, please check. error(%v)", err) |
|
err = ecode.MelloiUrlParseError |
|
return |
|
} |
|
if len(paramList.ParamList) > 0 { |
|
for _, paramList := range paramList.ParamList { |
|
if paramList.ID != id { |
|
tempList := strings.Split(u.RawQuery, "&") |
|
tempHeaderList := strings.Split(script.APIHeader, ",") |
|
tempArgumentList := strings.Split(script.ArgumentString, ",") |
|
tempDataList := strings.Split(script.Data, ",") |
|
//url params check |
|
if u.RawQuery != "" { |
|
if groupId, runOrder, flag, err = OrderEach(isEdit, tempList, paramList, scene.SceneType); err != nil || (runOrder != 1 && flag == 0) { |
|
return |
|
} |
|
} |
|
//APIHeader params check |
|
if script.APIHeader != "[{\"\":\"\"}]" && script.APIHeader != "[]" { |
|
if groupId, runOrder, flag, err = OrderEach(isEdit, tempHeaderList, paramList, scene.SceneType); err != nil || (runOrder != 1 && flag == 0) { |
|
return |
|
} |
|
} |
|
//ArgumentString params check |
|
if script.ArgumentString != "[{\"\":\"\"}]" && script.ArgumentString != "[]" { |
|
if groupId, runOrder, flag, err = OrderEach(isEdit, tempArgumentList, paramList, scene.SceneType); err != nil || (runOrder != 1 && flag == 0) { |
|
return |
|
} |
|
} |
|
//body params check |
|
if script.Data != "" { |
|
if groupId, runOrder, flag, err = OrderEach(isEdit, tempDataList, paramList, scene.SceneType); err != nil || (runOrder != 1 && flag == 0) { |
|
return |
|
} |
|
} |
|
} |
|
} |
|
} |
|
return |
|
} |
|
|
|
// OrderEach Order Each |
|
func OrderEach(isEdit bool, strList []string, paramList *model.Params, sceneType int) (groupId int, runOrder int, flag int, err error) { |
|
for _, paramPage := range strList { |
|
if strings.Contains(paramPage, "$") { |
|
tempParam := strings.Split(paramPage, "$")[1] |
|
param := RegularTrans(tempParam) |
|
//several params |
|
if strings.Contains(paramList.OutputParams, ",") { |
|
dbTempList := strings.Split(paramList.OutputParams, ",") |
|
for _, dbParam := range dbTempList { |
|
flag = 0 |
|
finalParam := strings.Split(strings.Split(dbParam, "\":\"")[0], "\"")[1] |
|
if param == finalParam { |
|
groupId = paramList.GroupID |
|
runOrder = paramList.RunOrder + 1 |
|
return |
|
} |
|
if !isEdit { |
|
if sceneType == 1 || sceneType == 0 { |
|
groupId = paramList.GroupID + 1 |
|
runOrder = 1 |
|
} else if sceneType == 2 { |
|
groupId = paramList.GroupID |
|
runOrder = paramList.RunOrder + 1 |
|
flag = 1 |
|
} |
|
} |
|
} |
|
} else { //single param |
|
dbParam := paramList.OutputParams |
|
finalParam := strings.Split(strings.Split(dbParam, "\":\"")[0], "\"")[1] |
|
if param == finalParam { |
|
groupId = paramList.GroupID |
|
runOrder = paramList.RunOrder + 1 |
|
return |
|
} |
|
if !isEdit { |
|
if sceneType == 1 || sceneType == 0 { |
|
groupId = paramList.GroupID + 1 |
|
runOrder = 1 |
|
} else if sceneType == 2 { |
|
groupId = paramList.GroupID |
|
runOrder = paramList.RunOrder + 1 |
|
flag = 1 |
|
} |
|
} |
|
} |
|
} else { |
|
if !isEdit { |
|
if sceneType == 1 || sceneType == 0 { |
|
groupId = paramList.GroupID + 1 |
|
runOrder = 1 |
|
} else if sceneType == 2 { |
|
groupId = paramList.GroupID |
|
runOrder = paramList.RunOrder + 1 |
|
flag = 1 |
|
} |
|
} |
|
} |
|
} |
|
return |
|
} |
|
|
|
// RegularTrans Regular Trans |
|
func RegularTrans(tempStr string) (targetStr string) { |
|
reg := regexp.MustCompile(`[\w]+`) |
|
str := reg.FindAllString(tempStr, -1) |
|
if len(str) != 0 { |
|
targetStr = str[0] |
|
} |
|
return targetStr |
|
}
|
|
|