script.go 39 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272
  1. package service
  2. import (
  3. "bytes"
  4. "context"
  5. "encoding/json"
  6. "html/template"
  7. "io"
  8. "net/url"
  9. "os"
  10. "regexp"
  11. "strconv"
  12. "strings"
  13. "time"
  14. "go-common/app/admin/ep/melloi/conf"
  15. "go-common/app/admin/ep/melloi/model"
  16. "go-common/library/ecode"
  17. "go-common/library/log"
  18. )
  19. //QueryScripts query scripts
  20. func (s *Service) QueryScripts(script *model.Script, pn, ps int) (scripts []*model.Script, err error) {
  21. if ps <= 0 || pn <= 0 {
  22. ps = 10
  23. pn = 1
  24. }
  25. if scripts, err = s.dao.QueryScripts(script, pn, ps); err != nil {
  26. log.Error("s.dao.QueryScripts error :(%v)", err)
  27. return
  28. }
  29. for _, script := range scripts {
  30. if script.APIHeader != "" {
  31. if err = json.Unmarshal([]byte(script.APIHeader), &script.Headers); err != nil {
  32. log.Error("get script header err : (%v), scriptId:(%d)", err, script.ID)
  33. }
  34. }
  35. if script.ArgumentString != "" {
  36. if err = json.Unmarshal([]byte(script.ArgumentString), &script.ArgumentsMap); err != nil {
  37. log.Error("get script argument err: (%v), scriptId:(%d)", err, script.ID)
  38. }
  39. }
  40. if script.OutputParams != "" {
  41. if err = json.Unmarshal([]byte(script.OutputParams), &script.OutputParamsMap); err != nil {
  42. log.Error("get script OutputParams err: (%v), scriptId:(%d)", err, script.ID)
  43. }
  44. }
  45. }
  46. return
  47. }
  48. //CountQueryScripts count query scripts
  49. func (s *Service) CountQueryScripts(script *model.Script) (total int) {
  50. return s.dao.CountQueryScripts(script)
  51. }
  52. //QueryScriptSnap query scriptSnap
  53. func (s *Service) QueryScriptSnap(scriptSnap *model.ScriptSnap) (snaps []*model.ScriptSnap, err error) {
  54. return s.dao.QueryScriptSnap(scriptSnap)
  55. }
  56. //QueryScriptsByPage query script by page
  57. func (s *Service) QueryScriptsByPage(c context.Context, sessionID string, qsrq *model.QueryScriptRequest) (rsp *model.QueryScriptResponse, err error) {
  58. // 获取服务树节点
  59. var (
  60. treeNodes []string
  61. treeNodesd []string
  62. )
  63. if treeNodesd, err = s.QueryUserRoleNode(c, sessionID); err != nil {
  64. log.Error("QueryUserRoleNode err (%v):", err)
  65. }
  66. treeNodes = append(treeNodesd, "")
  67. if ExistsInSlice(qsrq.Executor, conf.Conf.Melloi.Executor) {
  68. //rsp, err = s.dao.QueryScriptsByPageWhiteName(&qsrq.Script, qsrq.PageNum, qsrq.PageSize)
  69. if rsp, err = s.dao.QueryScriptsByPageWhiteName(&qsrq.Script, qsrq.PageNum, qsrq.PageSize); err != nil {
  70. return
  71. }
  72. } else {
  73. if rsp, err = s.dao.QueryScriptsByPage(&qsrq.Script, qsrq.PageNum, qsrq.PageSize, treeNodes); err != nil {
  74. return
  75. }
  76. }
  77. for _, script := range rsp.Scripts {
  78. if script.APIHeader != "" {
  79. if err = json.Unmarshal([]byte(script.APIHeader), &script.Headers); err != nil {
  80. log.Error("get script header err : (%v), scriptId:(%d)", err, script.ID)
  81. }
  82. }
  83. if script.ArgumentString != "" {
  84. if err = json.Unmarshal([]byte(script.ArgumentString), &script.ArgumentsMap); err != nil {
  85. log.Error("get script argument err: (%v), scriptId:(%d)", err, script.ID)
  86. }
  87. }
  88. if script.OutputParams != "" {
  89. if err = json.Unmarshal([]byte(script.OutputParams), &script.OutputParamsMap); err != nil {
  90. log.Error("get script OutputParams err: (%v), scriptId:(%d)", err, script.ID)
  91. }
  92. }
  93. }
  94. // 获取label
  95. for _, script := range rsp.Scripts {
  96. lr := model.LabelRelation{Type: model.ScriptType, TargetID: int64(script.ID)}
  97. if script.Labels, err = s.dao.QueryLabelRelation(&lr); err != nil {
  98. return
  99. }
  100. }
  101. return
  102. }
  103. //AddAndExcuScript add script and excute it
  104. func (s *Service) AddAndExcuScript(c context.Context, script *model.Script, cookie string, scene *model.Scene, fileWrite, convjson bool) (resp model.DoPtestResp, err error) {
  105. var (
  106. scriptID int
  107. groupID int
  108. runOrder int
  109. testNameNick string
  110. message string
  111. scriptd model.Script
  112. paramList *model.ParamList
  113. isEdit = false
  114. )
  115. if message, scriptd, err = s.AddScript(script, fileWrite); err != nil {
  116. log.Error("sorry, addScript fail : (%v)", err)
  117. return
  118. }
  119. headerString := MapToString(scriptd.Headers)
  120. argumentString := MapToString(scriptd.ArgumentsMap)
  121. scriptd.ArgumentString = argumentString
  122. scriptd.APIHeader = headerString
  123. scriptd.OutputParams = MapToString(scriptd.OutputParamsMap)
  124. //场景压测中选择已有接口时,去修改默认的熔断成功率的值(新增接口时不修改)
  125. if scene.IsBatch {
  126. scriptd.Fusing = scene.Fusing
  127. }
  128. if convjson {
  129. scriptd.ArgumentString = script.ArgumentString
  130. scriptd.APIHeader = script.APIHeader
  131. scriptd.OutputParams = script.OutputParams
  132. }
  133. //场景压测独有的逻辑
  134. if scriptd.TestType == model.SCENE_SCRIPT_TYPE {
  135. //根据接口参数依赖,计算出接口分组与执行顺序
  136. if paramList, err = s.dao.QueryParams(&scriptd, scene); err != nil {
  137. log.Error("s.dao.QueryParams err :(%v)", err)
  138. return
  139. }
  140. scriptd.GroupID, scriptd.RunOrder = GroupOrder(isEdit, &scriptd, scene, paramList)
  141. }
  142. //非debug 执行的 循环次数为-1 即永久
  143. if scriptd.Loops == -1 {
  144. if len(script.OutputParamsMap) == 0 || script.OutputParams == "[]" {
  145. scriptd.OutputParams = "[{\"\":\"\"}]"
  146. }
  147. if scriptID, groupID, runOrder, err = s.dao.AddScript(&scriptd); err != nil {
  148. log.Error("s.dao.AddScript err : (%v)", err)
  149. message = "sql excute err"
  150. return
  151. }
  152. }
  153. //如果不是复制脚本操作 或者 不是保存,则执行jmeter压测
  154. if !script.IsCopy && !script.IsSave {
  155. tim := strconv.FormatInt(time.Now().Unix(), 10)
  156. testNameNick = scriptd.TestName + tim
  157. log.Info("开始调用压测job-------\n")
  158. ptestParam := model.DoPtestParam{
  159. UserName: scriptd.UpdateBy, // 用户名
  160. LoadTime: scriptd.LoadTime, //运行时间
  161. TestNames: StringToSlice(scriptd.TestName), //接口名转数组
  162. FileName: scriptd.SavePath, // jmx文件
  163. ResJtl: scriptd.ResJtl, // jtl 文件
  164. JmeterLog: scriptd.JmeterLog, // jmeterlog时间戳
  165. Department: script.Department,
  166. Project: script.Project,
  167. APP: script.App,
  168. ScriptID: scriptID,
  169. IsDebug: script.IsDebug, //false
  170. Cookie: cookie, // 用不到
  171. URL: scriptd.URL, // 微信通知URL
  172. LabelIDs: script.LabelIds,
  173. Domain: scriptd.Domain,
  174. FileSplit: script.FileSplit, // 文件切割
  175. SplitNum: script.SplitNum, // 切割数量
  176. Fusing: script.Fusing,
  177. APIHeader: scriptd.APIHeader,
  178. ExecuDockerSum: script.ExecuDockerSum,
  179. UseBusinessStop: script.UseBusinessStop,
  180. BusinessStopPercent: script.BusinessStopPercent,
  181. }
  182. if resp, err = s.DoPtestByJmeter(c, ptestParam, StringToSlice(testNameNick)); err != nil {
  183. log.Error("DoPtestByJmeter err :(%v)", err)
  184. message = "DoPtestByJmeter err "
  185. return
  186. }
  187. resp.Message = message
  188. }
  189. resp.ScriptID = scriptID
  190. resp.GroupID = groupID
  191. resp.RunOrder = runOrder
  192. return
  193. }
  194. //AddScript add script
  195. func (s *Service) AddScript(script *model.Script, fileWrite bool) (message string, scriptd model.Script, err error) {
  196. var (
  197. buff *template.Template
  198. file *os.File
  199. scriptPath string
  200. u *url.URL
  201. sinfoJSON []byte
  202. JSON []byte
  203. JSONExtractors string
  204. dataFileName string
  205. Assertionsd []string
  206. )
  207. log.Info("threadsSum :(%d)", script.ThreadsSum)
  208. if script.LoadTime > s.c.Jmeter.TestTimeLimit {
  209. script.LoadTime = s.c.Jmeter.TestTimeLimit
  210. }
  211. //判断url
  212. if !strings.Contains(script.URL, "http://") && !strings.Contains(script.URL, "https://") {
  213. script.URL = "http://" + script.URL
  214. }
  215. if script.Delimiter == "" {
  216. script.Delimiter = ","
  217. }
  218. if u, err = url.Parse(script.URL); err != nil || u == nil {
  219. log.Error("sorry,url is not standard,error(%v)", err)
  220. err = ecode.MelloiUrlParseError
  221. return
  222. }
  223. if script.Data == "" {
  224. buff, err = template.ParseFiles(s.c.Jmeter.JmeterScUcodedTmp)
  225. } else {
  226. buff, err = template.ParseFiles(s.c.Jmeter.JmeterScTmp)
  227. }
  228. if err != nil {
  229. log.Error("open file failed! error %v", err)
  230. return
  231. }
  232. if script.Assertion != "" {
  233. script.UseAssertion = true
  234. Assertions := strings.Split(script.Assertion, "|")
  235. for _, assert := range Assertions {
  236. Assertionsd = append(Assertionsd, model.AssertionStart+assert+model.AssertionEnd)
  237. }
  238. script.AssertionString = unescaped(SliceToString(Assertionsd, " "))
  239. }
  240. if len(script.OutputParamsMap) > 0 && script.OutputParams != "[{\"\":\"\"}]" && script.OutputParams != "[]" && script.OutputParams != "" {
  241. if JSONExtractors, err = s.SetJSONExtractors(script); err != nil {
  242. return
  243. }
  244. if JSONExtractors != "" {
  245. script.JSONExtractor = unescaped(JSONExtractors)
  246. }
  247. }
  248. // POST 请求的 binary 逻辑
  249. if script.MultipartFile != "" && script.MultipartPath != "" {
  250. script.UseMultipart = true
  251. multiPartInfo := SetMultiPartInfo(script)
  252. script.MultiPartInfo = unescaped(multiPartInfo)
  253. }
  254. stringHeader := SetHeaders(script.Headers, script.ID)
  255. ArgmentStr := SetArguments(script.ArgumentsMap, script.ID)
  256. ArgmentString := unescaped(ArgmentStr)
  257. script.Arguments = ArgmentString
  258. stringHeaderd := unescaped(stringHeader)
  259. script.HeaderString = stringHeaderd
  260. script.ProcType = u.Scheme
  261. script.Domain = u.Hostname()
  262. script.Port = u.Port()
  263. if u.RawQuery == "" {
  264. script.Path = u.Path
  265. script.RowQuery = "appkey=" + conf.Conf.Melloi.AppkeyProd
  266. } else {
  267. script.Path = u.Path + "?" + u.RawQuery
  268. script.RowQuery = u.RawQuery + "&appkey=" + conf.Conf.Melloi.AppkeyProd
  269. }
  270. if script.UseSign {
  271. script.Path = u.Path + "?${params}"
  272. }
  273. dataFileName = script.FileName
  274. script.FileName = script.ScriptPath + script.FileName
  275. if script.ScriptPath != "" && script.FileName == "" && !script.Upload {
  276. message = "dataFile is not exists"
  277. log.Error(message)
  278. return
  279. }
  280. if script.Loops == 0 {
  281. script.Loops = -1
  282. }
  283. //极速模式(线程NIO模式)
  284. if script.IsAsync {
  285. script.AsyncInfo = unescaped(model.AsyncInfo)
  286. }
  287. //生成压测脚本
  288. if sinfoJSON, err = json.Marshal(script); err != nil {
  289. log.Error("script err (%v):", err)
  290. return
  291. }
  292. sc := string(sinfoJSON)
  293. log.Info("script :(%s)", sc)
  294. //判断是否使用内置参数
  295. if strings.Contains(sc, "${mid}") || strings.Contains(sc, "${access_key}") || script.UseSign {
  296. script.UseBuiltinParam = true
  297. }
  298. //fileWrite = true ,需要创建文件,为 false ,不需要创建文件
  299. if fileWrite {
  300. //创建脚本保存路径
  301. if script.ScriptPath == "" {
  302. if scriptPath, err = s.uniqueFolderPath(script.SavePath); err != nil {
  303. return
  304. }
  305. } else {
  306. scriptPath = script.ScriptPath
  307. }
  308. SavePath := scriptPath + script.TestName + "/"
  309. log.Info("SavePath****: " + SavePath)
  310. if err = os.MkdirAll(SavePath, 0755); err != nil {
  311. log.Error("Create SavePath Err :(%v)", err)
  312. return
  313. }
  314. ///创建脚本保存路径 脚本存放路径:部门/项目/应用/项目名/,须判断路径是否包含.jmx
  315. if !strings.Contains(script.SavePath, ".jmx") {
  316. // 创建脚本文件 部门/项目/应用/项目名/**.jmx
  317. if file, err = os.Create(SavePath + script.TestName + ".jmx"); err != nil {
  318. log.Error("create file error :(%v)", err)
  319. message = "create .jmx error"
  320. return
  321. }
  322. defer file.Close()
  323. //jtl 路径
  324. script.ResJtl = SavePath + script.TestName + ".jtl"
  325. //jmeter-log 路径
  326. script.JmeterLog = SavePath + script.TestName + ".log"
  327. } else {
  328. // 如果路径钟包含 .jmx ,则直接根据路径创建
  329. if file, err = os.Create(script.SavePath); err != nil {
  330. log.Error("create file error :(%v)", err)
  331. message = "create .jmx error"
  332. return
  333. }
  334. defer file.Close()
  335. }
  336. buff = buff.Funcs(template.FuncMap{"unescaped": unescaped})
  337. buff.Execute(io.Writer(file), script)
  338. script.SavePath = file.Name()
  339. }
  340. script.Ctime = time.Now()
  341. script.ProjectName = script.TestName
  342. if JSON, err = json.Marshal(script); err != nil {
  343. return
  344. }
  345. if err = json.Unmarshal([]byte(JSON), &scriptd); err != nil {
  346. log.Error("sorry,scriptd err(%v)", err)
  347. return
  348. }
  349. scriptd.HeaderString = stringHeaderd
  350. scriptd.Arguments = ArgmentString
  351. scriptd.JSONExtractor = script.JSONExtractor
  352. scriptd.Data = script.Data
  353. scriptd.FileName = dataFileName
  354. if script.FileName == "" || script.ParamsName == "" {
  355. scriptd.UseDataFile = false
  356. } else {
  357. scriptd.UseDataFile = true
  358. }
  359. if len(Assertionsd) > 0 {
  360. scriptd.AssertionString = unescaped(SliceToString(Assertionsd, " "))
  361. }
  362. return
  363. }
  364. //DelScript sel script
  365. func (s *Service) DelScript(id int) error {
  366. return s.dao.DelScript(id)
  367. }
  368. //UpdateScript update script info
  369. func (s *Service) UpdateScript(script *model.Script) (updateResult string, err error) {
  370. var (
  371. buff *template.Template
  372. stringHeader string
  373. Headers []map[string]string
  374. stringArgument string
  375. Arguments []map[string]string
  376. scriptd *model.Script
  377. u *url.URL
  378. file *os.File
  379. sinfoJSON []byte
  380. sinfoJSONd []byte
  381. JSONExtractors string
  382. Assertionsd []string
  383. )
  384. if scriptd, err = s.dao.QueryScriptByID(script.ID); err != nil {
  385. log.Error("query script fail , error %v", err)
  386. return
  387. }
  388. if script.Data == "" {
  389. buff, err = template.ParseFiles(s.c.Jmeter.JmeterScUcodedTmp)
  390. } else {
  391. buff, err = template.ParseFiles(s.c.Jmeter.JmeterScTmp)
  392. }
  393. if err != nil {
  394. log.Error("open file failed! error %v", err)
  395. return
  396. }
  397. if u, err = url.Parse(script.URL); err != nil || u == nil {
  398. log.Error("sorry,url is not standard,error(%v)", err)
  399. err = ecode.MelloiUrlParseError
  400. return
  401. }
  402. // 修改laodTime 和 threadsSum
  403. // ThreadGroup.ramp_time">{{.ReadyTime}}</stringProp>
  404. if file, err = os.Create(scriptd.SavePath); err != nil {
  405. log.Error("create file failed! error %v", err)
  406. return
  407. }
  408. defer file.Close()
  409. if err = json.Unmarshal([]byte(scriptd.APIHeader), &Headers); err != nil {
  410. updateResult = " scriptd.APIHeade json 不合法"
  411. log.Error("scriptd.APIHeader switch map failed! error %v", err)
  412. return
  413. }
  414. if err = json.Unmarshal([]byte(scriptd.ArgumentString), &Arguments); err != nil {
  415. updateResult = "scriptd.ArgumentString json 不合法"
  416. log.Error("scriptd.ArgumentString switch map failed! error %v", err)
  417. return
  418. }
  419. if len(scriptd.OutputParamsMap) > 0 && scriptd.OutputParams != "" && scriptd.OutputParams != "[{\"\":\"\"}]" && scriptd.OutputParams != "[]" {
  420. if err = json.Unmarshal([]byte(scriptd.OutputParams), &scriptd.OutputParamsMap); err != nil {
  421. log.Error("scriptd.OutputParams switch map failed! error %v", err)
  422. return
  423. }
  424. }
  425. stringHeader = SetHeaders(Headers, scriptd.ID)
  426. stringArgument = SetArguments(Arguments, scriptd.ID)
  427. if len(scriptd.OutputParamsMap) > 0 && scriptd.OutputParams != "[{\"\":\"\"}]" && scriptd.OutputParams != "[]" && script.OutputParams != "" {
  428. if JSONExtractors, err = s.SetJSONExtractors(scriptd); err != nil {
  429. return
  430. }
  431. if JSONExtractors != "" {
  432. script.JSONExtractor = unescaped(JSONExtractors)
  433. }
  434. }
  435. scriptd.HeaderString = unescaped(stringHeader)
  436. scriptd.Arguments = unescaped(stringArgument)
  437. scriptd.Data = script.Data
  438. scriptd.Assertion = script.Assertion
  439. scriptd.ReadyTime = script.ReadyTime
  440. scriptd.ThreadsSum = script.ThreadsSum
  441. scriptd.LoadTime = script.LoadTime
  442. scriptd.ProcType = u.Scheme
  443. scriptd.Domain = u.Hostname()
  444. scriptd.Port = u.Port()
  445. scriptd.TestName = script.TestName
  446. scriptd.FileName = scriptd.ScriptPath + scriptd.FileName
  447. if scriptd.Assertion != "" {
  448. scriptd.UseAssertion = true
  449. Assertions := strings.Split(scriptd.Assertion, "|")
  450. for _, assert := range Assertions {
  451. Assertionsd = append(Assertionsd, model.AssertionStart+assert+model.AssertionEnd)
  452. }
  453. scriptd.AssertionString = unescaped(SliceToString(Assertionsd, " "))
  454. }
  455. //判断是否使用内置参数
  456. if sinfoJSON, err = json.Marshal(script); err != nil {
  457. log.Error("script err :(%s)", err)
  458. return
  459. }
  460. if sinfoJSONd, err = json.Marshal(scriptd); err != nil {
  461. log.Error("script err :(%s)", err)
  462. return
  463. }
  464. sc := string(sinfoJSON) + string(sinfoJSONd)
  465. if strings.Contains(sc, "${mid}") || strings.Contains(sc, "${access_key}") || script.UseSign {
  466. scriptd.UseBuiltinParam = true
  467. }
  468. if u.RawQuery == "" {
  469. scriptd.Path = u.Path
  470. scriptd.RowQuery = "appkey=" + conf.Conf.Melloi.AppkeyProd
  471. } else {
  472. scriptd.Path = u.Path + "?" + u.RawQuery
  473. scriptd.RowQuery = u.RawQuery + "&appkey=" + conf.Conf.Melloi.AppkeyProd
  474. }
  475. if scriptd.UseSign {
  476. scriptd.Path = u.Path + "?${params}"
  477. }
  478. // POST 请求的 binary 逻辑
  479. if scriptd.MultipartFile != "" && scriptd.MultipartPath != "" {
  480. scriptd.UseMultipart = true
  481. multiPartInfo := SetMultiPartInfo(scriptd)
  482. scriptd.MultiPartInfo = unescaped(multiPartInfo)
  483. }
  484. if scriptd.IsAsync {
  485. scriptd.AsyncInfo = unescaped(model.AsyncInfo)
  486. }
  487. buff = buff.Funcs(template.FuncMap{"unescaped": unescaped})
  488. buff.Execute(io.Writer(file), scriptd)
  489. script.ProjectName = script.TestName
  490. script.KeepAlive = scriptd.KeepAlive
  491. if err = s.dao.UpdateScriptPart(script); err != nil {
  492. log.Error("s.dao.UpdateScript err :(%v)", err)
  493. return
  494. }
  495. updateResult = "success"
  496. return
  497. }
  498. //UpdateScriptAll update script all
  499. func (s *Service) UpdateScriptAll(script *model.Script, scene *model.Scene) (updateResult string, err error) {
  500. var (
  501. scriptd model.Script
  502. paramList *model.ParamList
  503. isEdit = true
  504. groupId int
  505. runOrder int
  506. fileWrite bool
  507. )
  508. id := script.ID
  509. script.ID = 0
  510. // script test_type 为1 表示 http 脚本
  511. if script.TestType == model.HTTP_SCRIPT_TYPE {
  512. fileWrite = true
  513. }
  514. if _, scriptd, err = s.AddScript(script, fileWrite); err != nil {
  515. log.Error("sorry, addScript fail : (%v)", err)
  516. return
  517. }
  518. if script.TestType == model.SCENE_SCRIPT_TYPE {
  519. //根据接口参数依赖,计算出接口分组与执行顺序
  520. if paramList, err = s.dao.QueryParams(&scriptd, scene); err != nil {
  521. log.Error("s.dao.QueryParams err :(%v)", err)
  522. return
  523. }
  524. groupId, runOrder = GroupOrderByEdit(isEdit, id, &scriptd, scene, paramList)
  525. if groupId != 0 && runOrder != 0 {
  526. scriptd.GroupID = groupId
  527. scriptd.RunOrder = runOrder
  528. }
  529. }
  530. scriptd.ID = id
  531. scriptd.SavePath = ""
  532. if scriptd.Loops == -1 {
  533. headerString := MapToString(scriptd.Headers)
  534. argumentString := MapToString(scriptd.ArgumentsMap)
  535. scriptd.OutputParams = MapToString(scriptd.OutputParamsMap)
  536. scriptd.ArgumentString = argumentString
  537. scriptd.APIHeader = headerString
  538. if err = s.dao.UpdateScript(&scriptd); err != nil {
  539. log.Error("s.dao.UpdateScript err : (%v)", err)
  540. return
  541. }
  542. }
  543. updateResult = "success"
  544. return
  545. }
  546. //AddJmeterSample add jmeter sample
  547. func (s *Service) AddJmeterSample(script *model.Script) (result string, err error) {
  548. var (
  549. buff *template.Template
  550. u *url.URL
  551. b = bytes.NewBuffer(nil)
  552. JSONExtractors string
  553. Assertionsd []string
  554. )
  555. if script.Data == "" {
  556. buff, err = template.ParseFiles(s.c.Jmeter.JmeterSampleTmp)
  557. } else {
  558. buff, err = template.ParseFiles(s.c.Jmeter.JmeterSamplePostTmp)
  559. }
  560. if err != nil {
  561. log.Info("open template failed! (%v)", err)
  562. return
  563. }
  564. //判断url
  565. if !strings.Contains(script.URL, "http://") && !strings.Contains(script.URL, "https://") {
  566. script.URL = "http://" + script.URL
  567. }
  568. if script.Delimiter == "" {
  569. script.Delimiter = ","
  570. }
  571. if u, err = url.Parse(script.URL); err != nil || u == nil {
  572. log.Error("sorry,url is not standard,error(%v)", err)
  573. err = ecode.MelloiUrlParseError
  574. return
  575. }
  576. stringHeader := SetHeaders(script.Headers, script.ID)
  577. ArgmentStr := SetArguments(script.ArgumentsMap, script.ID)
  578. ArgmentString := unescaped(ArgmentStr)
  579. if len(script.OutputParamsMap) > 0 && script.OutputParams != "[{\"\":\"\"}]" && script.OutputParams != "[]" && script.OutputParams != "" {
  580. if JSONExtractors, err = s.SetJSONExtractors(script); err != nil {
  581. return
  582. }
  583. if JSONExtractors != "" {
  584. script.JSONExtractor = unescaped(JSONExtractors)
  585. }
  586. }
  587. script.Arguments = ArgmentString
  588. stringHeaderd := unescaped(stringHeader)
  589. script.HeaderString = stringHeaderd
  590. script.ProcType = u.Scheme
  591. script.Domain = u.Hostname()
  592. script.Port = u.Port()
  593. script.FileName = script.ScriptPath + script.FileName
  594. if u.RawQuery == "" {
  595. script.Path = u.Path
  596. script.RowQuery = "appkey=" + conf.Conf.Melloi.AppkeyProd
  597. } else {
  598. script.Path = u.Path + "?" + u.RawQuery
  599. script.RowQuery = u.RawQuery + "&appkey=" + conf.Conf.Melloi.AppkeyProd
  600. }
  601. if script.UseSign {
  602. script.Path = u.Path + "?${params}"
  603. }
  604. if script.Assertion != "" {
  605. script.UseAssertion = true
  606. Assertions := strings.Split(script.Assertion, "|")
  607. for _, assert := range Assertions {
  608. Assertionsd = append(Assertionsd, model.AssertionStart+assert+model.AssertionEnd)
  609. }
  610. script.AssertionString = unescaped(SliceToString(Assertionsd, " "))
  611. }
  612. if script.ConstTimer > 0 && script.RandomTimer == 0 {
  613. constTimer := strings.Replace(model.ConstTimer, "1000", strconv.Itoa(script.ConstTimer), -1)
  614. script.ConstTimerInfo = unescaped(constTimer)
  615. }
  616. if script.ConstTimer > 0 && script.RandomTimer > 0 {
  617. constTimerd := strings.Replace(model.RandomTimer, "1000", strconv.Itoa(script.ConstTimer), -1)
  618. randomTimerd := strings.Replace(constTimerd, "500", strconv.Itoa(script.RandomTimer), -1)
  619. script.RandomTimerInfo = unescaped(randomTimerd)
  620. }
  621. buff = buff.Funcs(template.FuncMap{"unescaped": unescaped})
  622. buff.Execute(b, script)
  623. result = b.String()
  624. return
  625. }
  626. //AddThreadGroup add thread group
  627. func (s *Service) AddThreadGroup(script *model.Script, sceneType int) (result string, err error) {
  628. var (
  629. buff *template.Template
  630. scriptd model.Script
  631. b = bytes.NewBuffer(nil)
  632. )
  633. if _, scriptd, err = s.AddScript(script, false); err != nil {
  634. log.Error("s.AddScript err :(%v)", err)
  635. return
  636. }
  637. //并行get
  638. if sceneType == 1 && script.Data == "" {
  639. buff, err = template.ParseFiles(s.c.Jmeter.JmeterThGroupTmp)
  640. }
  641. //并行post
  642. if sceneType == 1 && script.Data != "" {
  643. buff, err = template.ParseFiles(s.c.Jmeter.JmeterThGroupPostTmp)
  644. }
  645. //串行get
  646. if sceneType == 2 && script.Data == "" {
  647. buff, err = template.ParseFiles(s.c.Jmeter.JmeterThGroupDuliTmp)
  648. }
  649. //串行 post
  650. if sceneType == 2 && script.Data != "" {
  651. buff, err = template.ParseFiles(s.c.Jmeter.JmeterThGroupPostDuliTmp)
  652. }
  653. if err != nil {
  654. log.Info("open template failed! (%v)", err)
  655. return
  656. }
  657. buff = buff.Funcs(template.FuncMap{"unescaped": unescaped})
  658. scriptd.FileName = scriptd.ScriptPath + scriptd.FileName
  659. buff.Execute(b, scriptd)
  660. result = b.String()
  661. return
  662. }
  663. //GetThreadGroup get thread group
  664. func (s *Service) GetThreadGroup(scrThreadGroup model.ScrThreadGroup) (threadGroup string, err error) {
  665. var (
  666. threadGroups []string
  667. IsSerial bool
  668. groups []int
  669. groupMap = make(map[int]int)
  670. RunOrders []int
  671. scriptsd []*model.Script
  672. scriptsds [][]*model.Script
  673. threadGroupd string
  674. threadGroupds []string
  675. threadSamples []string
  676. threadSample string
  677. threadSamplesd string
  678. threadGrou string
  679. )
  680. for _, script := range scrThreadGroup.Scripts {
  681. RunOrders = append(RunOrders, script.RunOrder)
  682. groupMap[script.GroupID]++
  683. if script.APIHeader != "" && script.APIHeader != "[{\"\":\"\"}]" {
  684. if err = json.Unmarshal([]byte(script.APIHeader), &script.Headers); err != nil {
  685. log.Error("get script header err : (%v), scriptId:(%d)", err, script.ID)
  686. }
  687. }
  688. if script.ArgumentString != "" && script.ArgumentString != "[{\"\":\"\"}]" {
  689. if err = json.Unmarshal([]byte(script.ArgumentString), &script.ArgumentsMap); err != nil {
  690. log.Error("get script argument err: (%v), scriptId:(%d)", err, script.ID)
  691. }
  692. }
  693. if script.OutputParams != "" && script.OutputParams != "[{\"\":\"\"}]" && script.OutputParams != "[]" {
  694. if err = json.Unmarshal([]byte(script.OutputParams), &script.OutputParamsMap); err != nil {
  695. log.Error("get script OutputParams err: (%v), scriptId:(%d)", err, script.ID)
  696. }
  697. }
  698. }
  699. for _, order := range RunOrders {
  700. if order > 1 {
  701. IsSerial = true
  702. break
  703. }
  704. }
  705. for k := range groupMap {
  706. groups = append(groups, k)
  707. }
  708. //并行脚本逻辑
  709. if !IsSerial {
  710. for _, script := range scrThreadGroup.Scripts {
  711. if threadGrou, err = s.AddThreadGroup(script, 1); err != nil {
  712. log.Error("d.GetThroupGroupJmeter: error(%v)", err)
  713. return
  714. }
  715. threadGroups = append(threadGroups, threadGrou)
  716. }
  717. for _, thgroup := range threadGroups {
  718. threadGroupd = threadGroupd + thgroup
  719. }
  720. threadGroup = threadGroupd
  721. return
  722. }
  723. //串行脚本逻辑
  724. for _, group := range groups {
  725. for i := 0; i < len(scrThreadGroup.Scripts); i++ {
  726. if scrThreadGroup.Scripts[i].GroupID == group {
  727. scriptsd = append(scriptsd, scrThreadGroup.Scripts[i])
  728. }
  729. }
  730. scriptsds = append(scriptsds, scriptsd)
  731. scriptsd = []*model.Script{}
  732. }
  733. // 每个线程组内的接口,按照接口的 RunOrder 属性进行排序
  734. for _, scriptsd := range scriptsds {
  735. for i := 0; i < len(scriptsd)-1; i++ {
  736. for j := i + 1; j < len(scriptsd); j++ {
  737. if scriptsd[i].RunOrder > scriptsd[j].RunOrder {
  738. tmp := scriptsd[i]
  739. scriptsd[i] = scriptsd[j]
  740. scriptsd[j] = tmp
  741. }
  742. }
  743. }
  744. }
  745. for k := 0; k < len(scriptsds); k++ {
  746. if len(scriptsds[k]) == 1 {
  747. if threadGroupd, err = s.AddThreadGroup(scriptsds[k][0], 1); err != nil {
  748. log.Error("d.GetThroupGroupJmeter: error(%v)", err)
  749. return
  750. }
  751. } else {
  752. //生成一个线程组,再往线程组插入 sample
  753. if threadGroupd, err = s.AddThreadGroup(scriptsds[k][0], 2); err != nil {
  754. log.Error(" s.AddScript err :(%v)", err)
  755. return
  756. }
  757. for i := 0; i < len(scriptsds[k]); i++ {
  758. //从第二个接口开始生成 sample
  759. if i > 0 {
  760. if threadSample, err = s.AddJmeterSample(scriptsds[k][i]); err != nil {
  761. log.Error("s.dao.GetThroupSeriesSample err :(%v)", err)
  762. return
  763. }
  764. threadSamples = append(threadSamples, threadSample)
  765. }
  766. }
  767. }
  768. for j := 0; j < len(threadSamples); j++ {
  769. threadSamplesd = threadSamplesd + threadSamples[j]
  770. }
  771. //生成一个 线程组
  772. threadGroupM := strings.Replace(threadGroupd, "+-+-+*", threadSamplesd, -1)
  773. //多个线程组
  774. threadGroupds = append(threadGroupds, threadGroupM)
  775. threadSamples = []string{}
  776. threadSamplesd = ""
  777. }
  778. for _, threadGrou := range threadGroupds {
  779. threadGroup = threadGroup + threadGrou
  780. }
  781. return
  782. }
  783. //URLCheck url check
  784. func (s *Service) URLCheck(script *model.Script) (urlEncode *model.URLEncode, err error) {
  785. var (
  786. tempUrl *url.URL
  787. )
  788. urlEncode = &model.URLEncode{}
  789. if strings.Contains(script.URL, "?") {
  790. if tempUrl, err = url.Parse(script.URL); err != nil {
  791. return
  792. }
  793. params := tempUrl.RawQuery
  794. paramList := strings.Split(params, "&")
  795. for _, param := range paramList {
  796. value := strings.Split(param, "=")[1]
  797. var myMap map[string]interface{}
  798. if err = json.Unmarshal([]byte(value), &myMap); err != nil {
  799. urlEncode.ParamsType = "nojson"
  800. urlEncode.NewUrl = script.URL
  801. continue
  802. }
  803. urlEncode.ParamsType = "json"
  804. newParams := tempUrl.Query().Encode()
  805. urlEncode.NewUrl = strings.Split(script.URL, "?")[0] + "?" + newParams
  806. return
  807. }
  808. }
  809. return
  810. }
  811. //AddTimer add Timer
  812. func (s *Service) AddTimer(script *model.Script) error {
  813. return s.dao.AddScriptTimer(script)
  814. }
  815. //SetHeaders set headers
  816. func SetHeaders(Headers []map[string]string, scriptId int) (stringHeader string) {
  817. var (
  818. stringHeaders []string
  819. HeaderString string
  820. )
  821. // 表示直接生成的脚本,非修改
  822. if scriptId == 0 {
  823. for _, header := range Headers {
  824. k := header["key"]
  825. v := header["value"]
  826. HeaderString = model.HeaderStart + k + model.HeaderMid + v + model.HeaderEnd
  827. stringHeaders = append(stringHeaders, HeaderString)
  828. }
  829. } else {
  830. //修改脚本,header 从数据库取出的
  831. for _, header := range Headers {
  832. for k, v := range header {
  833. HeaderString = model.HeaderStart + k + model.HeaderMid + v + model.HeaderEnd
  834. stringHeaders = append(stringHeaders, HeaderString)
  835. }
  836. }
  837. }
  838. for _, str := range stringHeaders {
  839. stringHeader = stringHeader + str + "\r\n"
  840. }
  841. return
  842. }
  843. //SetArguments set argument
  844. func SetArguments(Arguments []map[string]string, scriptId int) (stringArgument string) {
  845. var (
  846. stringArguments []string
  847. ArgumentString string
  848. )
  849. // 表示直接生成的脚本,非修改
  850. if scriptId == 0 {
  851. for _, argument := range Arguments {
  852. k := argument["key"]
  853. v := argument["value"]
  854. ArgumentString = model.ElementPropName + k + model.HTTPArgument + model.HTTPArgumentEncode + model.ArgumentStart + v + model.ArgumentMid + k + model.ArgumentEnd
  855. stringArguments = append(stringArguments, ArgumentString)
  856. }
  857. } else {
  858. //修改脚本,argument 从数据库取出的
  859. for _, argument := range Arguments {
  860. for k, v := range argument {
  861. ArgumentString = model.ElementPropName + k + model.HTTPArgument + model.HTTPArgumentEncode + model.ArgumentStart + v + model.ArgumentMid + k + model.ArgumentEnd
  862. stringArguments = append(stringArguments, ArgumentString)
  863. }
  864. }
  865. }
  866. for _, str := range stringArguments {
  867. stringArgument = stringArgument + str + "\r\n"
  868. }
  869. return
  870. }
  871. //SetJSONExtractor set JSONExtractorgo
  872. func (s *Service) SetJSONExtractor(jsonExt model.JSONExtractor) (JSONExtractor string, err error) {
  873. var (
  874. buff *template.Template
  875. b = bytes.NewBuffer(nil)
  876. )
  877. buff, err = template.ParseFiles(s.c.Jmeter.JSONExtractorTmp)
  878. if err != nil {
  879. log.Info("open template failed! (%v)", err)
  880. return
  881. }
  882. buff = buff.Funcs(template.FuncMap{"unescaped": unescaped})
  883. buff.Execute(b, jsonExt)
  884. JSONExtractor = b.String()
  885. return
  886. }
  887. //SetJSONExtractors Set JSONExtractors
  888. func (s *Service) SetJSONExtractors(script *model.Script) (JSONExtractors string, err error) {
  889. var (
  890. JSONExtractords []string
  891. jsonExt model.JSONExtractor
  892. JSONExtractord string
  893. )
  894. // 表示直接生成的脚本,非修改
  895. if script.ID == 0 {
  896. for _, OutputParam := range script.OutputParamsMap {
  897. jsonExt.JSONName = OutputParam["key"]
  898. jsonExt.JSONPath = OutputParam["value"]
  899. if jsonExt.JSONName != "" && jsonExt.JSONPath != "" {
  900. if JSONExtractord, err = s.SetJSONExtractor(jsonExt); err != nil {
  901. log.Error("SetJSONExtractor err :(%v) ", err)
  902. return
  903. }
  904. JSONExtractords = append(JSONExtractords, JSONExtractord)
  905. }
  906. }
  907. } else {
  908. //修改脚本,header 从数据库取出的
  909. for _, OutputParam := range script.OutputParamsMap {
  910. for k, v := range OutputParam {
  911. jsonExt.JSONName = k
  912. jsonExt.JSONPath = v
  913. }
  914. if jsonExt.JSONName != "" && jsonExt.JSONPath != "" {
  915. if JSONExtractord, err = s.SetJSONExtractor(jsonExt); err != nil {
  916. log.Error("SetJSONExtractor err :(%v) ", err)
  917. return
  918. }
  919. JSONExtractords = append(JSONExtractords, JSONExtractord)
  920. }
  921. }
  922. }
  923. JSONExtractors = SliceToString(JSONExtractords, " ")
  924. return
  925. }
  926. //SetMultiPartInfo Set MultiPartInfo
  927. func SetMultiPartInfo(script *model.Script) (multiPartInfo string) {
  928. multiPartInfo = model.MultipartName + script.MultipartPath + script.MultipartFile + model.MultipartFilePath +
  929. script.MultipartPath + script.MultipartFile + model.MultipartFilePathd + script.MultipartParam +
  930. model.MultipartMimetype + script.MimeType + model.MultipartEnd
  931. return
  932. }
  933. //MapToString map to string
  934. func MapToString(strMapArr []map[string]string) (headerString string) {
  935. for _, strMap := range strMapArr {
  936. k, keyOk := strMap["key"]
  937. v, valueOK := strMap["value"]
  938. if keyOk != valueOK {
  939. return
  940. }
  941. if keyOk {
  942. delete(strMap, "key")
  943. delete(strMap, "value")
  944. strMap[k] = v
  945. }
  946. }
  947. headers, _ := json.Marshal(strMapArr)
  948. headerString = string(headers)
  949. return
  950. }
  951. //StringToMap string to map
  952. func StringToMap(headerString string) (mapHeaders []map[string]string) {
  953. if headerString != "[{\"\":\"\"}]" {
  954. if err := json.Unmarshal([]byte(headerString), &mapHeaders); err != nil {
  955. return
  956. }
  957. }
  958. return
  959. }
  960. func unescaped(x string) interface{} {
  961. return template.HTML(x)
  962. }
  963. //HostInfo add hostinfo
  964. func HostInfo(domain string, apiHeader string) (hostInfo string) {
  965. mapHeaders := StringToMap(apiHeader)
  966. reg := regexp.MustCompile(`.com|.co`)
  967. strs := reg.FindAllString(domain, -1)
  968. if len(strs) != 0 {
  969. for _, str := range strs {
  970. if (strings.Contains(str, ".com") || strings.Contains(str, ".co")) && strings.Contains(apiHeader, domain) { //绑定至用户指定的ip
  971. for _, header := range mapHeaders {
  972. for host := range header {
  973. conf.Conf.Paas.HostInfo = domain + ":" + host
  974. hostInfo = conf.Conf.Paas.HostInfo
  975. }
  976. }
  977. } else if strings.Contains(str, ".com") || strings.Contains(str, ".co") { //默认绑定至172.22.22.222
  978. conf.Conf.Paas.HostInfo = domain + ":" + conf.Conf.Melloi.DefaultHost
  979. hostInfo = conf.Conf.Paas.HostInfo
  980. }
  981. }
  982. }
  983. return
  984. }
  985. //HostInfoList add hostinfo list
  986. func HostInfoList(scripts []*model.Script) (hostInfo string) {
  987. for _, script := range scripts {
  988. mapHeaders := StringToMap(script.APIHeader)
  989. reg := regexp.MustCompile(`.com|.co`)
  990. strs := reg.FindAllString(script.Domain, -1)
  991. if len(strs) != 0 {
  992. for _, str := range strs {
  993. if (strings.Contains(str, ".com") || strings.Contains(str, ".co")) && strings.Contains(script.APIHeader, script.Domain) { //绑定至用户指定的ip
  994. for _, header := range mapHeaders {
  995. for host := range header {
  996. conf.Conf.Paas.HostInfo = script.Domain + ":" + host
  997. hostInfo = conf.Conf.Paas.HostInfo
  998. }
  999. }
  1000. } else if strings.Contains(str, ".com") || strings.Contains(str, ".co") { //默认绑定至172.22.22.222
  1001. hostInfo = hostInfo + script.Domain + ":" + conf.Conf.Melloi.DefaultHost + ","
  1002. }
  1003. }
  1004. }
  1005. }
  1006. conf.Conf.Paas.HostInfo = hostInfo
  1007. return
  1008. }
  1009. //HostInfoByUploadSc host info By UploadSc
  1010. func HostInfoByUploadSc(domain string) (hostInfo string) {
  1011. domains := strings.Split(domain, ",")
  1012. for _, dom := range domains {
  1013. hostInfo = hostInfo + dom + ":" + conf.Conf.Melloi.DefaultHost + ","
  1014. }
  1015. conf.Conf.Paas.HostInfo = hostInfo
  1016. return
  1017. }
  1018. // GroupOrder Group Order
  1019. func GroupOrder(isEdit bool, script *model.Script, scene *model.Scene, paramList *model.ParamList) (groupId int, runOrder int) {
  1020. var (
  1021. flag = 0
  1022. //tmpIndex = 0
  1023. u *url.URL
  1024. err error
  1025. )
  1026. if u, err = url.Parse(script.URL); err != nil || u == nil {
  1027. log.Error("sorry, url is wrong, please check. error(%v)", err)
  1028. err = ecode.MelloiUrlParseError
  1029. return
  1030. }
  1031. if len(paramList.ParamList) > 0 {
  1032. for _, paramList := range paramList.ParamList {
  1033. tempList := strings.Split(u.RawQuery, "&")
  1034. tempHeaderList := strings.Split(script.APIHeader, ",")
  1035. tempArgumentList := strings.Split(script.ArgumentString, ",")
  1036. tempDataList := strings.Split(script.Data, ",")
  1037. if u.RawQuery == "" && (script.APIHeader == "[{\"\":\"\"}]" || script.APIHeader == "[]") && script.Data == "" && (script.ArgumentString == "[{\"\":\"\"}]" || script.ArgumentString == "[]") {
  1038. if scene.SceneType == 1 || scene.SceneType == 0 {
  1039. groupId = paramList.GroupID + 1
  1040. runOrder = 1
  1041. continue
  1042. } else if scene.SceneType == 2 {
  1043. groupId = paramList.GroupID
  1044. runOrder = paramList.RunOrder + 1
  1045. continue
  1046. }
  1047. }
  1048. //url params check
  1049. if u.RawQuery != "" {
  1050. if groupId, runOrder, flag, err = OrderEach(isEdit, tempList, paramList, scene.SceneType); err != nil || (runOrder != 1 && flag == 0) {
  1051. return
  1052. //} else if flag == 2 {
  1053. // tmpIndex = index
  1054. // break
  1055. }
  1056. }
  1057. //APIHeader params check
  1058. if script.APIHeader != "[{\"\":\"\"}]" && script.APIHeader != "[]" {
  1059. if groupId, runOrder, flag, err = OrderEach(isEdit, tempHeaderList, paramList, scene.SceneType); err != nil || (runOrder != 1 && flag == 0) {
  1060. return
  1061. }
  1062. }
  1063. //ArgumentString params check
  1064. if script.ArgumentString != "[{\"\":\"\"}]" && script.ArgumentString != "[]" {
  1065. if groupId, runOrder, flag, err = OrderEach(isEdit, tempArgumentList, paramList, scene.SceneType); err != nil || (runOrder != 1 && flag == 0) {
  1066. return
  1067. }
  1068. }
  1069. //body params check
  1070. if script.Data != "" {
  1071. if groupId, runOrder, flag, err = OrderEach(isEdit, tempDataList, paramList, scene.SceneType); err != nil || (runOrder != 1 && flag == 0) {
  1072. return
  1073. }
  1074. }
  1075. }
  1076. //for i := tmpIndex; i < len(paramList.ParamList); i++ {
  1077. // if err = s.dao.UpdateRunOrder(paramList.ParamList[i].); err != nil {
  1078. // log.Error("s.dao.UpdateScript err :(%v)", err)
  1079. // return
  1080. // }
  1081. //}
  1082. } else if script.GroupID != 0 {
  1083. groupId = script.GroupID
  1084. runOrder = 1
  1085. } else {
  1086. groupId = 1
  1087. runOrder = 1
  1088. }
  1089. return
  1090. }
  1091. // GroupOrderByEdit Group Order By Edit
  1092. func GroupOrderByEdit(isEdit bool, id int, script *model.Script, scene *model.Scene, paramList *model.ParamList) (groupId int, runOrder int) {
  1093. var (
  1094. flag = 0
  1095. //tmpIndex = 0
  1096. u *url.URL
  1097. err error
  1098. )
  1099. if u, err = url.Parse(script.URL); err != nil || u == nil {
  1100. log.Error("sorry, url is wrong, please check. error(%v)", err)
  1101. err = ecode.MelloiUrlParseError
  1102. return
  1103. }
  1104. if len(paramList.ParamList) > 0 {
  1105. for _, paramList := range paramList.ParamList {
  1106. if paramList.ID != id {
  1107. tempList := strings.Split(u.RawQuery, "&")
  1108. tempHeaderList := strings.Split(script.APIHeader, ",")
  1109. tempArgumentList := strings.Split(script.ArgumentString, ",")
  1110. tempDataList := strings.Split(script.Data, ",")
  1111. //url params check
  1112. if u.RawQuery != "" {
  1113. if groupId, runOrder, flag, err = OrderEach(isEdit, tempList, paramList, scene.SceneType); err != nil || (runOrder != 1 && flag == 0) {
  1114. return
  1115. }
  1116. }
  1117. //APIHeader params check
  1118. if script.APIHeader != "[{\"\":\"\"}]" && script.APIHeader != "[]" {
  1119. if groupId, runOrder, flag, err = OrderEach(isEdit, tempHeaderList, paramList, scene.SceneType); err != nil || (runOrder != 1 && flag == 0) {
  1120. return
  1121. }
  1122. }
  1123. //ArgumentString params check
  1124. if script.ArgumentString != "[{\"\":\"\"}]" && script.ArgumentString != "[]" {
  1125. if groupId, runOrder, flag, err = OrderEach(isEdit, tempArgumentList, paramList, scene.SceneType); err != nil || (runOrder != 1 && flag == 0) {
  1126. return
  1127. }
  1128. }
  1129. //body params check
  1130. if script.Data != "" {
  1131. if groupId, runOrder, flag, err = OrderEach(isEdit, tempDataList, paramList, scene.SceneType); err != nil || (runOrder != 1 && flag == 0) {
  1132. return
  1133. }
  1134. }
  1135. }
  1136. }
  1137. }
  1138. return
  1139. }
  1140. // OrderEach Order Each
  1141. func OrderEach(isEdit bool, strList []string, paramList *model.Params, sceneType int) (groupId int, runOrder int, flag int, err error) {
  1142. for _, paramPage := range strList {
  1143. if strings.Contains(paramPage, "$") {
  1144. tempParam := strings.Split(paramPage, "$")[1]
  1145. param := RegularTrans(tempParam)
  1146. //several params
  1147. if strings.Contains(paramList.OutputParams, ",") {
  1148. dbTempList := strings.Split(paramList.OutputParams, ",")
  1149. for _, dbParam := range dbTempList {
  1150. flag = 0
  1151. finalParam := strings.Split(strings.Split(dbParam, "\":\"")[0], "\"")[1]
  1152. if param == finalParam {
  1153. groupId = paramList.GroupID
  1154. runOrder = paramList.RunOrder + 1
  1155. return
  1156. }
  1157. if !isEdit {
  1158. if sceneType == 1 || sceneType == 0 {
  1159. groupId = paramList.GroupID + 1
  1160. runOrder = 1
  1161. } else if sceneType == 2 {
  1162. groupId = paramList.GroupID
  1163. runOrder = paramList.RunOrder + 1
  1164. flag = 1
  1165. }
  1166. }
  1167. }
  1168. } else { //single param
  1169. dbParam := paramList.OutputParams
  1170. finalParam := strings.Split(strings.Split(dbParam, "\":\"")[0], "\"")[1]
  1171. if param == finalParam {
  1172. groupId = paramList.GroupID
  1173. runOrder = paramList.RunOrder + 1
  1174. return
  1175. }
  1176. if !isEdit {
  1177. if sceneType == 1 || sceneType == 0 {
  1178. groupId = paramList.GroupID + 1
  1179. runOrder = 1
  1180. } else if sceneType == 2 {
  1181. groupId = paramList.GroupID
  1182. runOrder = paramList.RunOrder + 1
  1183. flag = 1
  1184. }
  1185. }
  1186. }
  1187. } else {
  1188. if !isEdit {
  1189. if sceneType == 1 || sceneType == 0 {
  1190. groupId = paramList.GroupID + 1
  1191. runOrder = 1
  1192. } else if sceneType == 2 {
  1193. groupId = paramList.GroupID
  1194. runOrder = paramList.RunOrder + 1
  1195. flag = 1
  1196. }
  1197. }
  1198. }
  1199. }
  1200. return
  1201. }
  1202. // RegularTrans Regular Trans
  1203. func RegularTrans(tempStr string) (targetStr string) {
  1204. reg := regexp.MustCompile(`[\w]+`)
  1205. str := reg.FindAllString(tempStr, -1)
  1206. if len(str) != 0 {
  1207. targetStr = str[0]
  1208. }
  1209. return targetStr
  1210. }