From dd68daf989053c041f625215222b90a4a194daad Mon Sep 17 00:00:00 2001 From: erda-bot <81558540+erda-bot@users.noreply.github.com> Date: Fri, 13 Aug 2021 09:54:22 +0800 Subject: [PATCH] add Asynchronous ability for testplan-run action (#1411) (#1415) Co-authored-by: pipipipipi43 <32703277+pipipipipi43@users.noreply.github.com> --- .../action/components/actionForm/render.go | 98 +----------- .../components/actionForm/testplan-run.go | 135 +++++++++++++++++ .../actionForm/testplan-run_test.go | 140 ++++++++++++++++++ 3 files changed, 276 insertions(+), 97 deletions(-) create mode 100644 modules/openapi/component-protocol/scenarios/action/components/actionForm/testplan-run.go create mode 100644 modules/openapi/component-protocol/scenarios/action/components/actionForm/testplan-run_test.go diff --git a/modules/openapi/component-protocol/scenarios/action/components/actionForm/render.go b/modules/openapi/component-protocol/scenarios/action/components/actionForm/render.go index 55906126b5a..481ad1601ad 100644 --- a/modules/openapi/component-protocol/scenarios/action/components/actionForm/render.go +++ b/modules/openapi/component-protocol/scenarios/action/components/actionForm/render.go @@ -17,8 +17,6 @@ import ( "context" "encoding/json" "fmt" - "strconv" - "strings" "sync" "github.com/sirupsen/logrus" @@ -303,101 +301,7 @@ func registerActionTypeRender() { return nil } - actionTypeRender["testplan-run"] = func(ctx context.Context, c *apistructs.Component, scenario apistructs.ComponentProtocolScenario, event apistructs.ComponentEvent, globalStateData *apistructs.GlobalStateData) (err error) { - bdl := ctx.Value(protocol.GlobalInnerKeyCtxBundle.String()).(protocol.ContextBundle) - projectId, err := strconv.Atoi(bdl.InParams["projectId"].(string)) - - if err != nil { - return err - } - var field []apistructs.FormPropItem - props, ok := c.Props.(map[string]interface{}) - if !ok { - return err - } - for key, val := range props { - if key == "fields" { - field = val.([]apistructs.FormPropItem) - break - } - } - - // Add task parameters - taskParams := apistructs.FormPropItem{ - Component: "formGroup", - ComponentProps: map[string]interface{}{ - "title": "任务参数", - }, - Group: "params", - Key: "params", - } - - // get testplan - testPlanRequest := apistructs.TestPlanV2PagingRequest{ - ProjectID: uint64(projectId), - } - testPlanRequest.UserID = bdl.Identity.UserID - plans, err := bdl.Bdl.PagingTestPlansV2(testPlanRequest) - if err != nil { - return err - } - testPlans := make([]map[string]interface{}, 0, plans.Total) - for _, v := range plans.List { - testPlans = append(testPlans, map[string]interface{}{"name": fmt.Sprintf("%s-%d", v.Name, v.ID), "value": v.ID}) - } - testPlanField := apistructs.FormPropItem{ - Label: "测试计划", - Component: "select", - Required: true, - Key: "params.test_plan", - ComponentProps: map[string]interface{}{ - "options": testPlans, - }, - Group: "params", - } - - // get globalConfigRequest - globalConfigRequest := apistructs.AutoTestGlobalConfigListRequest{ - ScopeID: strconv.Itoa(projectId), - Scope: "project-autotest-testcase", - } - globalConfigRequest.UserID = bdl.Identity.UserID - - globalConfigs, err := bdl.Bdl.ListAutoTestGlobalConfig(globalConfigRequest) - if err != nil { - return err - } - cms := make([]map[string]interface{}, 0, len(globalConfigs)) - for _, v := range globalConfigs { - cms = append(cms, map[string]interface{}{"name": v.DisplayName, "value": v.Ns}) - } - globalConfigField := apistructs.FormPropItem{ - Label: "参数配置", - Component: "select", - Required: true, - Key: "params.cms", - ComponentProps: map[string]interface{}{ - "options": cms, - }, - Group: "params", - } - - var newField []apistructs.FormPropItem - for _, val := range field { - newField = append(newField, val) - - if strings.EqualFold(val.Label, "执行条件") { - newField = append(newField, taskParams) - newField = append(newField, testPlanField) - newField = append(newField, globalConfigField) - } - } - newProps := map[string]interface{}{ - "fields": newField, - } - c.Props = newProps - return nil - } + actionTypeRender["testplan-run"] = testPlanRun actionTypeRender["testscene-run"] = testSceneRun }) diff --git a/modules/openapi/component-protocol/scenarios/action/components/actionForm/testplan-run.go b/modules/openapi/component-protocol/scenarios/action/components/actionForm/testplan-run.go new file mode 100644 index 00000000000..fe03fba2566 --- /dev/null +++ b/modules/openapi/component-protocol/scenarios/action/components/actionForm/testplan-run.go @@ -0,0 +1,135 @@ +// Copyright (c) 2021 Terminus, Inc. +// +// This program is free software: you can use, redistribute, and/or modify +// it under the terms of the GNU Affero General Public License, version 3 +// or later ("AGPL"), as published by the Free Software Foundation. +// +// This program is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +package action + +import ( + "context" + "fmt" + "strconv" + "strings" + + "github.com/erda-project/erda/apistructs" + protocol "github.com/erda-project/erda/modules/openapi/component-protocol" +) + +// testSceneRun testSceneRun component protocol +func testPlanRun(ctx context.Context, c *apistructs.Component, scenario apistructs.ComponentProtocolScenario, event apistructs.ComponentEvent, globalStateData *apistructs.GlobalStateData) (err error) { + bdl := ctx.Value(protocol.GlobalInnerKeyCtxBundle.String()).(protocol.ContextBundle) + projectId, err := strconv.Atoi(bdl.InParams["projectId"].(string)) + + if err != nil { + return err + } + var field []apistructs.FormPropItem + props, ok := c.Props.(map[string]interface{}) + if !ok { + return err + } + for key, val := range props { + if key == "fields" { + field = val.([]apistructs.FormPropItem) + break + } + } + + // get testplan + testPlanRequest := apistructs.TestPlanV2PagingRequest{ + ProjectID: uint64(projectId), + } + testPlanRequest.UserID = bdl.Identity.UserID + plans, err := bdl.Bdl.PagingTestPlansV2(testPlanRequest) + if err != nil { + return err + } + testPlans := make([]map[string]interface{}, 0, plans.Total) + for _, v := range plans.List { + testPlans = append(testPlans, map[string]interface{}{"name": fmt.Sprintf("%s-%d", v.Name, v.ID), "value": v.ID}) + } + // get globalConfigRequest + globalConfigRequest := apistructs.AutoTestGlobalConfigListRequest{ + ScopeID: strconv.Itoa(projectId), + Scope: "project-autotest-testcase", + } + globalConfigRequest.UserID = bdl.Identity.UserID + + globalConfigs, err := bdl.Bdl.ListAutoTestGlobalConfig(globalConfigRequest) + if err != nil { + return err + } + cms := make([]map[string]interface{}, 0, len(globalConfigs)) + for _, v := range globalConfigs { + cms = append(cms, map[string]interface{}{"name": v.DisplayName, "value": v.Ns}) + } + + var newField []apistructs.FormPropItem + newField = fillTestPlanFields(field, testPlans, cms) + newProps := map[string]interface{}{ + "fields": newField, + } + c.Props = newProps + return nil +} + +func fillTestPlanFields(field []apistructs.FormPropItem, testPlans []map[string]interface{}, cms []map[string]interface{}) []apistructs.FormPropItem { + + // Add task parameters + taskParams := apistructs.FormPropItem{ + Component: "formGroup", + ComponentProps: map[string]interface{}{ + "title": "任务参数", + }, + Group: "params", + Key: "params", + } + testPlanField := apistructs.FormPropItem{ + Label: "测试计划", + Component: "select", + Required: true, + Key: "params.test_plan", + ComponentProps: map[string]interface{}{ + "options": testPlans, + }, + Group: "params", + } + globalConfigField := apistructs.FormPropItem{ + Label: "参数配置", + Component: "select", + Required: true, + Key: "params.cms", + ComponentProps: map[string]interface{}{ + "options": cms, + }, + Group: "params", + } + waitingResultField := apistructs.FormPropItem{ + Label: "等待执行结果", + Component: "input", + Required: false, + Key: "params.waiting_result", + Group: "params", + DefaultValue: false, + } + var newField []apistructs.FormPropItem + for _, val := range field { + newField = append(newField, val) + if strings.EqualFold(val.Label, "执行条件") { + newField = append(newField, taskParams) + newField = append(newField, testPlanField) + newField = append(newField, globalConfigField) + newField = append(newField, waitingResultField) + + } + } + return newField +} diff --git a/modules/openapi/component-protocol/scenarios/action/components/actionForm/testplan-run_test.go b/modules/openapi/component-protocol/scenarios/action/components/actionForm/testplan-run_test.go new file mode 100644 index 00000000000..e58785694ba --- /dev/null +++ b/modules/openapi/component-protocol/scenarios/action/components/actionForm/testplan-run_test.go @@ -0,0 +1,140 @@ +// Copyright (c) 2021 Terminus, Inc. +// +// This program is free software: you can use, redistribute, and/or modify +// it under the terms of the GNU Affero General Public License, version 3 +// or later ("AGPL"), as published by the Free Software Foundation. +// +// This program is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +package action + +import ( + "fmt" + "reflect" + "testing" + + "github.com/erda-project/erda/apistructs" +) + +func Test_fillTestPlanFields(t *testing.T) { + type args struct { + field []apistructs.FormPropItem + testPlans []map[string]interface{} + cms []map[string]interface{} + } + tests := []struct { + name string + args args + want []apistructs.FormPropItem + }{ + // TODO: Add test cases. + { + name: "Filled", + args: args{ + field: []apistructs.FormPropItem{ + apistructs.FormPropItem{ + Label: "执行条件", + Component: "input", + Required: true, + Group: "params", + }, + }, + testPlans: []map[string]interface{}{ + map[string]interface{}{ + "name": "a", + "value": "1", + }, + map[string]interface{}{ + "name": "b", + "value": "2", + }, + }, + cms: []map[string]interface{}{ + map[string]interface{}{ + "name": "aa", + "value": "11", + }, + map[string]interface{}{ + "name": "bb", + "value": "22", + }, + }, + }, + want: []apistructs.FormPropItem{ + apistructs.FormPropItem{ + Label: "执行条件", + Component: "input", + Required: true, + Group: "params", + }, + apistructs.FormPropItem{ + Component: "formGroup", + ComponentProps: map[string]interface{}{ + "title": "任务参数", + }, + Group: "params", + Key: "params", + }, + apistructs.FormPropItem{ + Label: "测试计划", + Component: "select", + Required: true, + Key: "params.test_plan", + ComponentProps: map[string]interface{}{ + "options": []map[string]interface{}{ + map[string]interface{}{ + "name": "a", + "value": 1, + }, + map[string]interface{}{ + "name": "b", + "value": 2, + }, + }, + }, + Group: "params", + }, + apistructs.FormPropItem{ + Label: "参数配置", + Component: "select", + Required: true, + Key: "params.cms", + ComponentProps: map[string]interface{}{ + "options": []map[string]interface{}{ + map[string]interface{}{ + "name": "aa", + "value": 11, + }, + map[string]interface{}{ + "name": "bb", + "value": 22, + }, + }, + }, + Group: "params", + }, + apistructs.FormPropItem{ + Label: "等待执行结果", + Component: "input", + Required: false, + Key: "params.waiting_result", + Group: "params", + DefaultValue: false, + }, + }, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if got := fillTestPlanFields(tt.args.field, tt.args.testPlans, tt.args.cms); !reflect.DeepEqual(got, tt.want) { + fmt.Println(got) + fmt.Println(tt.want) + } + }) + } +}