diff --git a/modules/openapi/component-protocol/scenarios/auto-test-plan-detail/components/executeTaskTable/render.go b/modules/openapi/component-protocol/scenarios/auto-test-plan-detail/components/executeTaskTable/render.go index 2bc922f31d1..5d520a48ddb 100644 --- a/modules/openapi/component-protocol/scenarios/auto-test-plan-detail/components/executeTaskTable/render.go +++ b/modules/openapi/component-protocol/scenarios/auto-test-plan-detail/components/executeTaskTable/render.go @@ -20,6 +20,7 @@ import ( "encoding/json" "fmt" "strconv" + "time" "github.com/sirupsen/logrus" @@ -214,6 +215,12 @@ func getProps() map[string]interface{} { Width: 85, Ellipsis: true, }, + { + Title: "执行时间", + DataIndex: "time", + Width: 85, + Ellipsis: true, + }, { Title: "接口路径", DataIndex: "path", @@ -323,6 +330,7 @@ func (a *ExecuteTaskTable) setData(pipeline *apistructs.PipelineDetailDTO) error "status": getStatus(task.Status), "type": transformStepType(apistructs.StepAPIType(task.Type)), "path": "", + "time": a.getCostTime(task), } lists = append(lists, list) ret-- @@ -398,6 +406,7 @@ func (a *ExecuteTaskTable) setData(pipeline *apistructs.PipelineDetailDTO) error "status": getStatus(task.Status), "type": transformStepType(res.Type), "path": path, + "time": a.getCostTime(task), } if task.SnippetPipelineID != nil && (res.Type == apistructs.StepTypeScene || @@ -432,6 +441,7 @@ func (a *ExecuteTaskTable) setData(pipeline *apistructs.PipelineDetailDTO) error "status": getStatus(task.Status), "type": transformStepType(apistructs.AutotestSceneSet), "path": "", + "time": a.getCostTime(task), } if task.SnippetPipelineDetail != nil { list["tasksNum"] = task.SnippetPipelineDetail.DirectSnippetTasksNum @@ -464,6 +474,7 @@ func (a *ExecuteTaskTable) setData(pipeline *apistructs.PipelineDetailDTO) error "status": getStatus(task.Status), "type": transformStepType(apistructs.AutotestScene), "path": "", + "time": a.getCostTime(task), } if task.SnippetPipelineDetail != nil { list["tasksNum"] = task.SnippetPipelineDetail.DirectSnippetTasksNum @@ -488,6 +499,15 @@ func (a *ExecuteTaskTable) setData(pipeline *apistructs.PipelineDetailDTO) error return nil } +// getCostTime the format of time is "00:00:00" +// id is not end status or err return "-" +func (a *ExecuteTaskTable) getCostTime(task apistructs.PipelineTaskDTO) string { + if !task.Status.IsEndStatus() { + return "-" + } + return time.Unix(task.CostTimeSec, 0).In(time.UTC).Format("15:04:05") +} + func (a *ExecuteTaskTable) marshal(c *apistructs.Component) error { stateValue, err := json.Marshal(a.State) if err != nil { diff --git a/modules/openapi/component-protocol/scenarios/auto-test-plan-detail/components/executeTaskTable/render_test.go b/modules/openapi/component-protocol/scenarios/auto-test-plan-detail/components/executeTaskTable/render_test.go index 70c91d88899..ee3b3e9d8ce 100644 --- a/modules/openapi/component-protocol/scenarios/auto-test-plan-detail/components/executeTaskTable/render_test.go +++ b/modules/openapi/component-protocol/scenarios/auto-test-plan-detail/components/executeTaskTable/render_test.go @@ -21,6 +21,7 @@ import ( "github.com/alecthomas/assert" "github.com/erda-project/erda/apistructs" + "github.com/erda-project/erda/bundle" protocol "github.com/erda-project/erda/modules/openapi/component-protocol" ) @@ -44,3 +45,49 @@ func Test_handlerListOperation(t *testing.T) { } assert.NoError(t, err) } + +func TestGetCostTime(t *testing.T) { + tt := []struct { + task apistructs.PipelineTaskDTO + want string + }{ + { + apistructs.PipelineTaskDTO{ + Status: apistructs.PipelineStatusRunning, + }, + "-", + }, + { + apistructs.PipelineTaskDTO{ + Status: apistructs.PipelineStatusSuccess, + IsSnippet: false, + CostTimeSec: 59, + }, + "00:00:59", + }, + { + apistructs.PipelineTaskDTO{ + Status: apistructs.PipelineStatusSuccess, + IsSnippet: false, + CostTimeSec: 3600, + }, + "01:00:00", + }, + { + apistructs.PipelineTaskDTO{ + Status: apistructs.PipelineStatusSuccess, + IsSnippet: true, + CostTimeSec: 59*60 + 59, + }, + "00:59:59", + }, + } + r := ExecuteTaskTable{ + CtxBdl: protocol.ContextBundle{ + Bdl: bundle.New(), + }, + } + for _, v := range tt { + assert.Equal(t, v.want, r.getCostTime(v.task)) + } +} diff --git a/modules/pipeline/dbclient/op_pipeline_task.go b/modules/pipeline/dbclient/op_pipeline_task.go index 6b06a26a72e..ad958cdbaa3 100644 --- a/modules/pipeline/dbclient/op_pipeline_task.go +++ b/modules/pipeline/dbclient/op_pipeline_task.go @@ -189,6 +189,28 @@ func (client *Client) UpdatePipelineTaskStatus(id uint64, status apistructs.Pipe return err } +// UpdatePipelineTaskTime update the costTime,timeBegin and timeEnd of pipeline task +func (client *Client) UpdatePipelineTaskTime(p *spec.Pipeline, ops ...SessionOption) error { + session := client.NewSession(ops...) + defer session.Close() + + if p.TimeBegin == nil || p.TimeBegin.IsZero() { + p.TimeBegin = p.TimeCreated + } + if p.TimeEnd == nil || p.TimeEnd.IsZero() { + p.TimeEnd = p.TimeUpdated + } + timeBegin, timeEnd := *p.TimeBegin, *p.TimeEnd + + costTimeSec := p.CostTimeSec + if costTimeSec == -1 { + costTimeSec = int64(timeEnd.Sub(timeBegin).Seconds()) + } + _, err := session.ID(p.ParentTaskID).Cols("cost_time_sec", "time_begin", "time_end"). + Update(&spec.PipelineTask{CostTimeSec: costTimeSec, TimeBegin: timeBegin, TimeEnd: timeEnd}) + return err +} + func (client *Client) UpdatePipelineTaskContext(id uint64, ctx spec.PipelineTaskContext, ops ...SessionOption) error { session := client.NewSession(ops...) defer session.Close() diff --git a/modules/pipeline/pipengine/reconciler/snippet.go b/modules/pipeline/pipengine/reconciler/snippet.go index c462e2333be..fc318df54ee 100644 --- a/modules/pipeline/pipengine/reconciler/snippet.go +++ b/modules/pipeline/pipengine/reconciler/snippet.go @@ -55,6 +55,10 @@ func (r *Reconciler) fulfillParentSnippetTask(p *spec.Pipeline) error { if err := r.dbClient.UpdatePipelineTaskStatus(*p.ParentTaskID, calcStatus); err != nil { return err } + // update the costTime,timeBegin,timeEnd of pipeline task + if err := r.dbClient.UpdatePipelineTaskTime(p); err != nil { + return err + } return nil }