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.
691 lines
22 KiB
691 lines
22 KiB
package service |
|
|
|
import ( |
|
"context" |
|
"fmt" |
|
"io/ioutil" |
|
"os" |
|
"regexp" |
|
"strconv" |
|
"strings" |
|
"time" |
|
|
|
"go-common/app/admin/ep/melloi/conf" |
|
"go-common/app/admin/ep/melloi/model" |
|
"go-common/library/log" |
|
) |
|
|
|
//DoPtest do post |
|
func (s *Service) DoPtest(c context.Context, ptestParam model.DoPtestParam) (resp model.DoPtestResp, err error) { |
|
var ( |
|
testNameNick string |
|
testNameNicks []string |
|
) |
|
if ptestParam.TestNameNick == "" { |
|
tim := strconv.FormatInt(time.Now().Unix(), 10) |
|
for _, testName := range ptestParam.TestNames { |
|
testNameNick = testName + tim |
|
testNameNicks = append(testNameNicks, testNameNick) |
|
} |
|
} |
|
return s.DoPtestByJmeter(c, ptestParam, testNameNicks) |
|
} |
|
|
|
//StopPtest stop test |
|
func (s *Service) StopPtest(c context.Context, ptestJob model.PtestJob) (err error) { |
|
var ( |
|
jobNames []string |
|
ptestJobs []*model.PtestJob |
|
) |
|
ptestJob.Active = 1 |
|
if ptestJobs, err = s.dao.QueryPtestJob(&ptestJob); err != nil { |
|
log.Error("s.dao.QueryPtestJob err :(%v)", err) |
|
return |
|
} |
|
for _, ptestJob := range ptestJobs { |
|
jobNames = append(jobNames, ptestJob.JobName) |
|
} |
|
for _, jobName := range jobNames { |
|
s.DeleteJob(context.TODO(), jobName) |
|
} |
|
return |
|
} |
|
|
|
//ReducePtest reduce ptest |
|
func (s *Service) ReducePtest(c context.Context, reducePtest model.ReducePtest) (message string, err error) { |
|
if reducePtest.JobName == "" { |
|
message = "请输入 jobName" |
|
return |
|
} |
|
if _, err = s.DeleteJob(c, reducePtest.JobName); err != nil { |
|
message = "调用删除 job 接口失败" |
|
log.Error("s.DeleteJob err :(%v)", err) |
|
return |
|
} |
|
if err = s.dao.DeletePtestJob(reducePtest.ID); err != nil { |
|
message = "sql 执行失败" |
|
log.Error("s.dao.DeletePtestJob err :(%v)", err) |
|
return |
|
} |
|
message = "success" |
|
return |
|
} |
|
|
|
//QueryAllJobFree Query AllJob Free |
|
func (s *Service) QueryAllJobFree(c context.Context, ptesJob *model.PtestJob) ([]*model.PtestJob, error) { |
|
return s.dao.QueryPtestJob(ptesJob) |
|
} |
|
|
|
//QueryOrStopAllPtestByJobName query or stop all test by job name |
|
func (s *Service) QueryOrStopAllPtestByJobName(c context.Context, reportSuID int, IsDelete bool, testStatus int) (ptestjobsd []*model.PtestJob, err error) { |
|
|
|
// 删除所有正在允许此接口的容器 |
|
ptestJobd := model.PtestJob{ReportSuID: reportSuID, Active: 1} |
|
if ptestjobsd, err = s.dao.QueryPtestJob(&ptestJobd); err != nil { |
|
log.Error("s.dao.QueryPtestJob err (%v)", err) |
|
return |
|
} |
|
|
|
if IsDelete { |
|
for _, ptestJob := range ptestjobsd { |
|
if _, err = s.DeleteJob(context.TODO(), ptestJob.JobName); err != nil { |
|
log.Error("s.DeleteJob err :(%v)", err) |
|
return |
|
} |
|
if err = s.dao.DeletePtestJob(ptestJob.ID); err != nil { |
|
log.Error("s.dao.DeletePtestJob err (%v)", err) |
|
return |
|
} |
|
if err = s.dao.UpdateReportStatusByID(reportSuID, testStatus); err != nil { |
|
log.Error("s.UpdateReportStatusByID err :(%v)", err) |
|
return |
|
} |
|
} |
|
} |
|
return |
|
} |
|
|
|
//DoAddPtest doadd test stress |
|
func (s *Service) DoAddPtest(c context.Context, ptestAdd model.PtestAdd) (status string, err error) { |
|
status = "fail" |
|
var ( |
|
resp model.DoPtestResp |
|
grpc *model.GRPC |
|
scripts []*model.Script |
|
resportSumm []*model.ReportSummary |
|
) |
|
ptestParam := model.DoPtestParam{} |
|
// 此处 ScriptType 取自 reportSummary , 0-http 1-grpc 2-scene |
|
if ptestAdd.ScriptType == model.PROTOCOL_GRPC { |
|
if grpc, err = s.QueryGrpcById(ptestAdd.ScriptID); err != nil { |
|
log.Error("Query GRPC err: (%v)", err) |
|
return status, err |
|
} |
|
ptestParam = model.DoPtestParam{ |
|
UserName: grpc.UpdateBy, // 用户名 |
|
LoadTime: grpc.LoadTime, //运行时间 |
|
TestNames: StringToSlice(grpc.TaskName), //接口名转数组 |
|
FileName: grpc.JmxPath, // jmx文件 |
|
ResJtl: ptestAdd.ResJtl, // jtl时间戳 |
|
JmeterLog: ptestAdd.JmeterLog, // jmeterlog时间戳 |
|
Department: grpc.Department, |
|
Project: grpc.Project, |
|
IsDebug: false, |
|
APP: grpc.APP, |
|
ScriptID: grpc.ID, |
|
Cookie: "", // 用不到 |
|
URL: grpc.ServiceName, // 用于微信通知 |
|
LabelIDs: nil, |
|
Domain: grpc.HostName, // 微信通知Domain |
|
FileSplit: false, // 文件切割 |
|
SplitNum: 0, // 切割数量 |
|
JarPath: grpc.JarPath, |
|
Type: model.PROTOCOL_GRPC, //grpc |
|
AddPtest: true, // 加压 |
|
} |
|
} |
|
if ptestAdd.ScriptType == model.PROTOCOL_SCENE { |
|
ptestScene := model.DoPtestSceneParam{ |
|
SceneID: ptestAdd.SceneId, |
|
UserName: ptestAdd.UserName, |
|
} |
|
if resp, err = s.DoScenePtest(c, ptestScene, true, ""); err != nil { |
|
log.Error("s.DoScenePtest err :(%v)", err) |
|
return status, err |
|
} |
|
} |
|
if ptestAdd.ScriptType == model.PROTOCOL_HTTP { |
|
script := model.Script{ID: ptestAdd.ScriptID} |
|
if scripts, err = s.QueryScripts(&script, 1, 5); err != nil { |
|
log.Error("QueryScripts err :(%v)", err) |
|
return status, err |
|
} |
|
if len(scripts) > 0 { |
|
// http 模板 |
|
ptestParam = model.DoPtestParam{ |
|
UserName: script.UpdateBy, |
|
TestNames: QueryTestNamesByJmfile(scripts[0].SavePath), |
|
FileName: scripts[0].SavePath, |
|
LoadTime: 1800, |
|
Upload: scripts[0].Upload, |
|
ProjectName: scripts[0].ProjectName, |
|
ResJtl: ptestAdd.ResJtl, |
|
JmeterLog: ptestAdd.JmeterLog, |
|
Department: scripts[0].Department, |
|
Project: scripts[0].Project, |
|
APP: scripts[0].App, |
|
ScriptID: scripts[0].ID, |
|
AddPtest: true, |
|
Domain: scripts[0].Domain, |
|
FileSplit: scripts[0].FileSplit, |
|
SplitNum: scripts[0].SplitNum, |
|
DockerSum: ptestAdd.DockerSum, |
|
Type: model.PROTOCOL_HTTP, |
|
APIHeader: scripts[0].APIHeader, |
|
} |
|
} |
|
} |
|
if ptestAdd.ScriptType != model.PROTOCOL_SCENE { |
|
if resp, err = s.DoPtestByJmeter(c, ptestParam, nil); err != nil { |
|
log.Error("DoPtestByJmeter err: (%v)", err) |
|
return |
|
} |
|
log.Info("add ---jobName:(%s)", resp.JobName) |
|
} |
|
status = "success" |
|
|
|
// 更新reportSummary数据表 |
|
reportSu := model.ReportSummary{ID: ptestAdd.ReportSuID} |
|
if resportSumm, err = s.dao.QueryReportSurys(&reportSu); err != nil { |
|
return |
|
} |
|
ptestJob := model.PtestJob{JobName: resp.JobName, ScriptID: ptestAdd.ScriptID, ReportSuID: ptestAdd.ReportSuID, Active: 1, ExecuteID: ptestAdd.ExecuteID, HostIP: resp.HostIP} |
|
log.Info("add ---jobName:(%s)", resp.JobName) |
|
if _, err = s.dao.AddPtestJob(&ptestJob); err != nil { |
|
log.Error("s.dao.AddPtestJob err (%v)", err) |
|
return |
|
} |
|
DockerSum := resportSumm[0].DockerSum + 1 |
|
if err = s.dao.UpdateReportDockByID(resportSumm[0].ID, DockerSum); err != nil { |
|
log.Error("s.dao.UpdateReportDockByID err (%v)", err) |
|
return |
|
} |
|
return |
|
} |
|
|
|
//AddPtest add ptest |
|
func (s *Service) AddPtest(c context.Context, ptestAdd model.PtestAdd) (err error) { |
|
go s.DoAddPtestWithSleep(c, ptestAdd) |
|
return |
|
} |
|
|
|
//DoAddPtestWithSleep Do AddPtestWith Sleep |
|
func (s *Service) DoAddPtestWithSleep(c context.Context, ptestAdd model.PtestAdd) (err error) { |
|
var ptestJobs []*model.PtestJob |
|
if ptestAdd.DockerNum == 0 { |
|
ptestAdd.DockerNum = 1 |
|
} |
|
if ptestAdd.SleepTime == 0 { |
|
ptestAdd.SleepTime = 1 |
|
} |
|
for i := 1; i <= ptestAdd.DockerNum; i++ { |
|
time.Sleep(time.Duration(ptestAdd.SleepTime) * time.Second) |
|
|
|
// 判断主容器状态,主容器被删除,则不再添加新的容器 |
|
ptestJob := model.PtestJob{JobName: ptestAdd.JobName} |
|
if ptestJobs, err = s.dao.QueryPtestJob(&ptestJob); err != nil { |
|
log.Error("s.dao.QueryPtestJob err :(%v)", err) |
|
} |
|
if len(ptestJobs) > 0 { |
|
if ptestJobs[0].Active != -1 { |
|
go s.DoAddPtest(context.TODO(), ptestAdd) |
|
} |
|
} |
|
} |
|
return |
|
} |
|
|
|
//DoPtestByFile do test by file |
|
func (s *Service) DoPtestByFile(c context.Context, script model.Script, resJtl, jmeterLog string) (resp model.DoPtestResp, err error) { |
|
var scripts []*model.Script |
|
if scripts, err = s.QueryScripts(&script, 1, 5); err != nil { |
|
log.Error("QueryScripts err :(%v)", err) |
|
return |
|
} |
|
scriptID := scripts[0].ID |
|
testNames := QueryTestNamesByJmfile(scripts[0].SavePath) |
|
ptestParam := model.DoPtestParam{ |
|
UserName: script.UpdateBy, |
|
TestNames: testNames, |
|
FileName: scripts[0].SavePath, |
|
LoadTime: 1800, |
|
Upload: scripts[0].Upload, |
|
ProjectName: scripts[0].ProjectName, |
|
ResJtl: resJtl, |
|
JmeterLog: jmeterLog, |
|
Department: scripts[0].Department, |
|
Project: scripts[0].Project, |
|
APP: scripts[0].App, |
|
ScriptID: scripts[0].ID, |
|
Fusing: scripts[0].Fusing, |
|
UseBusinessStop: scripts[0].UseBusinessStop, |
|
BusinessStopPercent: scripts[0].BusinessStopPercent, |
|
} |
|
if resp, err = s.DoPtest(context.TODO(), ptestParam); err != nil { |
|
log.Error("DoPtest error :(%v)", err) |
|
return |
|
} |
|
resp.ScriptID = scriptID |
|
return |
|
} |
|
|
|
//DoPtestArr QueryScriptsInID |
|
func (s *Service) DoPtestArr(c context.Context, PtestBatch model.PtestBatch, cookie string) (status string, err error) { |
|
var scripts []*model.Script |
|
if scripts, err = s.dao.QueryScriptsInID(PtestBatch.IDArr); err != nil { |
|
status = "fail" |
|
log.Error("QueryScriptsInID err --- :(%v) ", err) |
|
return status, err |
|
} |
|
|
|
for _, script := range scripts { |
|
JmeterLog := script.JmeterLog + strconv.FormatInt(time.Now().Unix(), 10) |
|
ResJtl := script.ResJtl + strconv.FormatInt(time.Now().Unix(), 10) |
|
|
|
ptestParam := model.DoPtestParam{ |
|
UserName: PtestBatch.UserName, |
|
FileName: script.SavePath, |
|
ProjectName: script.ProjectName, |
|
Upload: script.Upload, |
|
ResJtl: ResJtl, |
|
JmeterLog: JmeterLog, |
|
Department: script.Department, |
|
Project: script.Project, |
|
APP: script.App, |
|
ScriptID: script.ID, |
|
URL: script.URL, |
|
Cookie: cookie, |
|
Domain: script.Domain, |
|
FileSplit: script.FileSplit, |
|
SplitNum: script.SplitNum, |
|
Fusing: script.Fusing, |
|
APIHeader: script.APIHeader, |
|
} |
|
if script.Upload { |
|
ptestParam.LoadTime = 1800 |
|
ptestParam.TestNames = QueryTestNamesByJmfile(script.SavePath) |
|
} else { |
|
ptestParam.LoadTime = script.LoadTime |
|
ptestParam.TestNames = StringToSlice(script.TestName) |
|
} |
|
go s.DoPtest(context.TODO(), ptestParam) |
|
} |
|
status = "success" |
|
return |
|
} |
|
|
|
//DoPtestByScriptId do ptest by scriptid |
|
func (s *Service) DoPtestByScriptId(c context.Context, script *model.Script, cookie, executor string) (resp model.DoPtestResp, err error) { |
|
var scripts []*model.Script |
|
if scripts, err = s.QueryScripts(script, 1, 5); err != nil { |
|
log.Error("QueryScripts err :(%v)", err) |
|
return |
|
} |
|
ptestParam := model.DoPtestParam{ |
|
TestNames: StringToSlice(scripts[0].TestName), |
|
ProjectName: scripts[0].ProjectName, |
|
FileName: scripts[0].SavePath, |
|
LoadTime: scripts[0].LoadTime, |
|
ResJtl: scripts[0].ResJtl, |
|
JmeterLog: scripts[0].JmeterLog, |
|
UserName: executor, |
|
Department: scripts[0].Department, |
|
Project: scripts[0].Project, |
|
APP: scripts[0].App, |
|
ScriptID: scripts[0].ID, |
|
URL: scripts[0].URL, |
|
Cookie: cookie, |
|
Domain: scripts[0].Domain, |
|
FileSplit: scripts[0].FileSplit, |
|
SplitNum: scripts[0].SplitNum, |
|
Fusing: scripts[0].Fusing, |
|
APIHeader: scripts[0].APIHeader, |
|
Upload: scripts[0].Upload, |
|
UseBusinessStop: scripts[0].UseBusinessStop, |
|
BusinessStopPercent: scripts[0].BusinessStopPercent, |
|
} |
|
|
|
if ptestParam.Upload { |
|
ptestParam.TestNames = QueryTestNamesByJmfile(scripts[0].SavePath) |
|
} |
|
return s.DoPtest(c, ptestParam) |
|
} |
|
|
|
//DoPtestByJmeter do ptest by jmeter |
|
func (s *Service) DoPtestByJmeter(c context.Context, ptestParam model.DoPtestParam, testNameNicks []string) (resp model.DoPtestResp, err error) { |
|
var ( |
|
du string |
|
Debug int |
|
CPUCore int |
|
reportSuID int |
|
scriptSnapIDs []int |
|
beginTime string |
|
token string |
|
Index = 0 |
|
btm time.Time |
|
dus time.Duration |
|
tempRes *model.PaasJobQueryStatus |
|
hostIP string |
|
command string |
|
) |
|
lay := "2006-01-02 15:04:05" |
|
executeID := strconv.FormatInt(time.Now().UTC().UnixNano(), 10) |
|
if !ptestParam.AddPtest { |
|
// 不加压,增加新的 log |
|
ptestParam.ResJtl = fmt.Sprintf("%s%s", ptestParam.ResJtl, executeID) |
|
ptestParam.JmeterLog = fmt.Sprintf("%s%s", ptestParam.JmeterLog, executeID) |
|
} |
|
jobNamed := executeID + "run" |
|
jobName := string([]rune(jobNamed)[10:]) |
|
|
|
// add filesplit messages to env variables |
|
if !ptestParam.AddPtest { |
|
Index = 1 |
|
} else { |
|
Index = ptestParam.DockerSum + 1 |
|
} |
|
ptestParam.EnvInfo = "FileSplit:" + strconv.FormatBool(ptestParam.FileSplit) + ",SplitNum:" + strconv.Itoa(ptestParam.SplitNum) + |
|
",Index:" + strconv.Itoa(Index) |
|
|
|
// 为压测容器绑定host |
|
if ptestParam.Upload { |
|
HostInfoByUploadSc(ptestParam.Domain) |
|
} else { |
|
if ptestParam.Type == model.PROTOCOL_HTTP { |
|
HostInfo(ptestParam.Domain, ptestParam.APIHeader) |
|
} else if ptestParam.Type == model.PROTOCOL_SCENE { |
|
HostInfoList(ptestParam.Scripts) |
|
} |
|
} |
|
|
|
if _, _, err = CreateResJtlAndJmeterLog(ptestParam); err != nil { |
|
log.Info("create resjtl or jmeterlog err :(%v)", err) |
|
return |
|
} |
|
//获取 Debug,CPUCore,command |
|
Debug, CPUCore, command = s.CreateCommand(ptestParam) |
|
|
|
jobInfo := model.Job{FileName: ptestParam.FileName, CPU: CPUCore, Memory: 8096, Parallelism: 1, Name: jobName, ResJtl: ptestParam.ResJtl, |
|
JmeterLog: ptestParam.JmeterLog, EnvInfo: ptestParam.EnvInfo, JarPath: ptestParam.JarPath, Command: command} |
|
|
|
beginTime = time.Now().Format(lay) |
|
if btm, err = time.Parse(lay, beginTime); err != nil { |
|
return |
|
} |
|
resd := int(btm.Unix()) % 5 |
|
du = "-" + strconv.Itoa(resd) + "s" |
|
if dus, err = time.ParseDuration(du); err != nil { |
|
return |
|
} |
|
|
|
beginTime = btm.Add(dus).Format(lay) |
|
res := make(chan interface{}, 10000) |
|
resHostIp := make(chan interface{}, 10000) |
|
tm := time.Now() |
|
for i := 0; i <= ptestParam.LoadTime+10; i += 5 { |
|
tm = tm.Add(time.Second * 5) |
|
} |
|
timeout := time.After(time.Until(tm)) |
|
log.Info("job set timeout util --- :(%s) ", time.Until(tm)) |
|
|
|
if ptestParam.ExecuDockerSum == 0 { |
|
ptestParam.ExecuDockerSum = 1 |
|
} |
|
if _, err = s.AddJob(context.TODO(), jobInfo); err != nil { |
|
log.Error("add ptest job err:(%v)", err) |
|
return |
|
} |
|
if token, err = s.RmToken(c); err != nil { |
|
log.Error("get token err:(%v)", err) |
|
return |
|
} |
|
//获取物理机ip |
|
if tempRes, err = s.Job(c, jobName); err != nil { |
|
hostIP = "" |
|
} |
|
if len(tempRes.Data.Pods) > 0 { |
|
hostIP = tempRes.Data.Pods[0].HostIP |
|
} |
|
|
|
// 如果不是增加容器,生成一份快照 |
|
if !ptestParam.AddPtest { |
|
if scriptSnapIDs, err = s.AddSnap(c, ptestParam, executeID, jobName, jobNamed); err != nil || len(scriptSnapIDs) == 0 { |
|
s.DeleteJob(context.TODO(), jobName) |
|
return |
|
} |
|
// 从页面上直接输入参数生成的单场景脚本,testNames 和 testNameNicks 长度都是 1,reportSummary 测试计划为空 |
|
if reportSuID, err = s.AddReSummaryByPtest(ptestParam, jobName, jobNamed, testNameNicks, scriptSnapIDs[0], Debug); err != nil { |
|
log.Error("s.dao.AddReportSummary err :(%v)", err) |
|
s.DeleteJob(context.TODO(), jobName) |
|
return |
|
} |
|
//容器写入 ptest_job 表 |
|
ptestJob := model.PtestJob{ScriptID: ptestParam.ScriptID, ReportSuID: reportSuID, JobName: jobName, Active: 1, ExecuteID: jobNamed, HostIP: hostIP} |
|
if _, err = s.dao.AddPtestJob(&ptestJob); err != nil { |
|
log.Error("s.dao.AddPtestJob err :(%v)", err) |
|
s.DeleteJob(context.TODO(), jobName) |
|
return |
|
} |
|
//获取场景中每个接口的熔断成功率的值 |
|
fusingList := make([]int, len(ptestParam.Scripts)) |
|
useBusiStopList := make([]bool, len(ptestParam.Scripts)) |
|
busiStopPercentList := make([]int, len(ptestParam.Scripts)) |
|
for index, script := range ptestParam.Scripts { |
|
fusingList[index] = script.Fusing |
|
useBusiStopList[index] = script.UseBusinessStop |
|
busiStopPercentList[index] = script.BusinessStopPercent |
|
} |
|
AddReGraphTimer := model.AddReGraphTimer{ |
|
ScriptID: ptestParam.ScriptID, |
|
JobName: jobName, |
|
BeginTime: beginTime, |
|
Token: token, |
|
TestNames: ptestParam.TestNames, |
|
TestNameNicks: testNameNicks, |
|
ReportSuID: reportSuID, |
|
Fusing: ptestParam.Fusing, |
|
FusingList: fusingList, |
|
TestType: ptestParam.Type, |
|
UseBusinessStop: ptestParam.UseBusinessStop, |
|
BusinessStopPercent: ptestParam.BusinessStopPercent, |
|
UseBusiStopList: useBusiStopList, |
|
BusiStopPercentList: busiStopPercentList, |
|
} |
|
//场景脚本的逻辑,可能存在多个test_name |
|
if ptestParam.Type == model.PROTOCOL_SCENE && ptestParam.TestNameNick != "" { |
|
AddReGraphTimer.TestNameNicks = ptestParam.TestNameNicks |
|
AddReGraphTimer.TestNames = ptestParam.TestNames |
|
} |
|
//数据同步job |
|
log.Info("-------开始执行数据同步job,loadTime :(%v)", ptestParam.LoadTime) |
|
go s.addReGraphTimer(context.TODO(), AddReGraphTimer, res, timeout) |
|
|
|
//查询容器hostIp |
|
go s.addPtestJobHostIp(context.TODO(), AddReGraphTimer, resHostIp, timeout) |
|
//增加label |
|
if len(ptestParam.LabelIDs) > 0 && !ptestParam.IsDebug { |
|
for _, lableID := range ptestParam.LabelIDs { |
|
lrl := model.LabelRelation{LabelID: int64(lableID), Type: model.ScriptType, TargetID: int64(ptestParam.ScriptID)} |
|
s.AddLabelRelation(&lrl) |
|
lrll := model.LabelRelation{LabelID: int64(lableID), Type: model.ReportType, TargetID: int64(reportSuID)} |
|
s.AddLabelRelation(&lrll) |
|
} |
|
} |
|
//如果不是debug ,且配置发生通知为true,则发送微信通知 |
|
if !ptestParam.IsDebug && conf.Conf.Wechat.SendMessage { |
|
serviceName := ptestParam.Department + "." + ptestParam.Project + "." + ptestParam.APP |
|
var userService map[string][]string |
|
if userService, err = s.QueryDependServiceAdmins(c, serviceName, s.getSessionInCookie(ptestParam.Cookie)); err != nil { |
|
log.Error("query depend service admin error(%v)", err) |
|
return |
|
} |
|
// 发送群通知 |
|
content := AddWechatContent(ptestParam, reportSuID, jobName, userService) |
|
go s.AddWechatSend(context.TODO(), ptestParam.Cookie, content) |
|
|
|
// 发送依赖服务通知 |
|
for user := range userService { |
|
toUser := StringToSlice(user) |
|
content = AddWechatDependServiceContent(ptestParam, userService, reportSuID, user) |
|
go s.dao.PushWechatMsgToPerson(context.TODO(), ptestParam.Cookie, toUser, content) |
|
} |
|
} |
|
} |
|
resp = model.DoPtestResp{BeginTime: beginTime, ReportSuID: reportSuID, JobName: jobName, ScriptSnapIDs: scriptSnapIDs, |
|
JmeterLog: ptestParam.JmeterLog, JtlLog: ptestParam.ResJtl, JmxFile: ptestParam.FileName, LoadTime: ptestParam.LoadTime, HostIP: hostIP} |
|
return |
|
} |
|
|
|
//QueryTestNameNick query test nick name |
|
func QueryTestNameNick(TestName string, testNameNicks []string) (testNameNick string) { |
|
for _, testNameNickd := range testNameNicks { |
|
if strings.Contains(testNameNickd, TestName) { |
|
testNameNick = testNameNickd |
|
break |
|
} |
|
} |
|
return testNameNick |
|
} |
|
|
|
//IsUniqObject check whether object is unique |
|
func IsUniqObject(aa []string) (t bool) { |
|
for _, a := range aa { |
|
if a == aa[0] { |
|
t = true |
|
continue |
|
} |
|
|
|
if a != aa[0] { |
|
t = false |
|
break |
|
} |
|
} |
|
return t |
|
} |
|
|
|
//StringToSlice convert string to string slice |
|
func StringToSlice(str string) (strs []string) { |
|
strs = append(strs, str) |
|
return |
|
} |
|
|
|
//RemoveRepByMap 去除切片钟的重复元素 |
|
func RemoveRepByMap(slc []string) (result []string) { |
|
tempMap := map[string]byte{} // 存放不重复主键 |
|
for _, e := range slc { |
|
l := len(tempMap) |
|
tempMap[e] = 0 |
|
if len(tempMap) != l { // 加入map后,map长度变化,则元素不重复 |
|
result = append(result, e) |
|
} |
|
} |
|
return result |
|
} |
|
|
|
//SliceToString join slice elements to string |
|
func SliceToString(strs []string, inter string) (result string) { |
|
for _, str := range strs { |
|
result = result + inter + str |
|
} |
|
return string([]rune(result)[1:]) |
|
} |
|
|
|
//QueryTestNamesByJmfile query test names by jmeter file |
|
func QueryTestNamesByJmfile(fileName string) (testNames []string) { |
|
var ( |
|
buff []byte |
|
err error |
|
) |
|
if buff, err = ioutil.ReadFile(fileName); err != nil { |
|
log.Error("open script file failed! error %v", err) |
|
return |
|
} |
|
reg := regexp.MustCompile("SampleGui\"(.*)\" enabled=\"true") |
|
reg2 := regexp.MustCompile("testname=\"(.*)\" enabled=\"true") |
|
results := reg.FindAllString(string(buff), -1) |
|
for _, res := range results { |
|
resd := reg2.FindString(res) |
|
resdd := strings.Replace(resd, "\" enabled=\"true", "", -1) |
|
resddd := strings.Replace(resdd, "testname=\"", "", -1) |
|
testNames = append(testNames, resddd) |
|
} |
|
return |
|
} |
|
|
|
//ExistsInSlice check whether the string in the slice |
|
func ExistsInSlice(str string, strs []string) bool { |
|
for _, st := range strs { |
|
if st == str { |
|
return true |
|
} |
|
} |
|
return false |
|
} |
|
|
|
//PingDomain ping domain |
|
func PingDomain(ptestParam model.DoPtestParam) (pingString string) { |
|
var pingStrings []string |
|
if ptestParam.Type == model.PROTOCOL_HTTP { |
|
pingString = " ping -c 1 " + ptestParam.Domain + " |tee -a " + ptestParam.JmeterLog |
|
} else if ptestParam.Type == model.PROTOCOL_SCENE { |
|
for _, script := range ptestParam.Scripts { |
|
pingStrings = append(pingStrings, " ping -c 1 "+script.Domain+" |tee -a "+ptestParam.JmeterLog) |
|
} |
|
pingString = SliceToString(pingStrings, "&") |
|
} |
|
return |
|
} |
|
|
|
//CreateResJtlAndJmeterLog Create ResJt lAnd JmeterLog |
|
func CreateResJtlAndJmeterLog(ptestParam model.DoPtestParam) (ResJtlFile, JmeterLogFile *os.File, err error) { |
|
if ptestParam.ResJtl != "" { |
|
if ResJtlFile, err = os.Create(ptestParam.ResJtl); err != nil { |
|
log.Error("create ResJtl error :(%v)", err) |
|
return |
|
} |
|
ResJtlFile.WriteString("此处显示 err 日志") |
|
defer ResJtlFile.Close() |
|
} |
|
if ptestParam.JmeterLog != "" { |
|
if JmeterLogFile, err = os.Create(ptestParam.JmeterLog); err != nil { |
|
log.Error("create JmeterLog error :(%v)", err) |
|
return |
|
} |
|
JmeterLogFile.WriteString("此处显示启动日志,执行debug 则显示debug 日志") |
|
defer JmeterLogFile.Close() |
|
} |
|
return |
|
} |
|
|
|
//CreateCommand Create Command |
|
func (s *Service) CreateCommand(ptestParam model.DoPtestParam) (debug, CPUCore int, command string) { |
|
// ping 所有接口的 domain |
|
pingString := PingDomain(ptestParam) |
|
|
|
cpJar := "" |
|
if ptestParam.JarPath != "" { |
|
cpJar = fmt.Sprintf("cp %s %s & ", ptestParam.JarPath, s.c.Jmeter.JmeterExtLibPathContainer) |
|
} |
|
|
|
// 调试逻辑 |
|
if ptestParam.IsDebug { |
|
CPUCore = s.c.Paas.CPUCoreDebug |
|
debug = 1 |
|
command = cpJar + " mkdir /data/jmeter-log & jmeter -n -t " + ptestParam.FileName + " -j " + ptestParam.JmeterLog + " -l " + ptestParam.ResJtl + " -F ;" + pingString |
|
} else { |
|
CPUCore = s.c.Paas.CPUCore |
|
debug = -1 |
|
command = cpJar + " mkdir /data/jmeter-log & jmeter -n -t " + ptestParam.FileName + " -j " + ptestParam.JmeterLog + " -l " + ptestParam.ResJtl + " -F" |
|
} |
|
return |
|
}
|
|
|