Skip to content

Commit

Permalink
add custom autotest run
Browse files Browse the repository at this point in the history
Signed-off-by: Maksim Paskal <paskal.maksim@gmail.com>
  • Loading branch information
maksim-paskal committed Nov 7, 2023
1 parent 4ec5375 commit c46759d
Show file tree
Hide file tree
Showing 5 changed files with 190 additions and 38 deletions.
48 changes: 48 additions & 0 deletions front/components/AutotestCustomAction.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
<template>
<div>
<DropDown ref="autotestBranch" id="autotestBranch" text="Select branch"
:endpoint="`/api/project-refs?id=${this.customAction.ProjectID}`" />
<ul style="list-style-type: none;padding-left: 0px;">
<li style="margin-top: 10px">
<pre style="margin-bottom: 0px">Autotest type</pre>
<b-form-select v-model="test" class="form-select" :options="this.customAction.Tests" />
</li>

<li style="margin-top: 10px" v-bind:key="index" v-for="(env, index) in this.customAction.Env">
<pre style="margin-bottom: 0px">{{ env.Description }}</pre>
<b-form-input class="autotest-env" :name="env.Name" :value="env.Default" />
</li>
</ul>
</div>
</template>
<script>
export default {
props: ["customAction"],
data() {
return {
test: "",
}
},
mounted() {
if (this.customAction.Tests.length == 1) {
this.test = this.customAction.Tests[0];
}
},
methods: {
getInput() {
const inputCollection = document.getElementsByClassName("autotest-env");
let selectedEnv = {};
for (let i = 0; i < inputCollection.length; i++) {
selectedEnv[inputCollection[i].name] = inputCollection[i].value;
}
return {
Ref: this.$refs.autotestBranch.selected,
Test: this.test,
Env: selectedEnv,
}
}
}
}
</script>
13 changes: 12 additions & 1 deletion front/pages/_environmentID/autotests.vue
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
<b-button style="margin-right: 10px" v-bind:key="index" v-for="(item, index) in this.data.Result.Actions"
target="_blank" @click="startAutotest(item)">&nbsp;{{ item.Name
}}</b-button>
<b-button @click="showCustomDialog()">Custom autotest</b-button>
</div>
<b-card-group v-if="this.data.Result.LastPipelines" style="margin-bottom:15px">
<b-card :title="getCardTitle(item)" v-bind:key="index" v-for="(item, index) in this.data.Result.LastPipelines">
Expand Down Expand Up @@ -46,6 +47,10 @@
<b-button variant="light" title="Get more results" v-if="data.Result.HasMorePipelines" @click="getMoreResults()"><em
class="bi bi-arrow-clockwise" /></b-button>
</div>
<b-modal centered id="bv-custom-dialog" @ok="createCustomRun()" title="Create custom run">
<AutotestCustomAction ref="autotestCustomAction" v-if="this.data.Result?.CustomAction"
:customAction="this.data.Result.CustomAction" />
</b-modal>
</div>
</template>
<script>
Expand Down Expand Up @@ -84,14 +89,20 @@ export default {
},
methods: {
startAutotest(item) {
this.call('make-start-autotest', { Test: item.Test, User: this.user.user })
this.call('make-start-autotest', { Test: item.Test })
},
getCardTitle(item) {
return `${item.Test}`
},
getMoreResults() {
this.size += 10;
this.$router.app.refresh();
},
showCustomDialog() {
this.$bvModal.show('bv-custom-dialog')
},
createCustomRun() {
this.call('make-start-autotest-custom', this.$refs.autotestCustomAction.getInput())
}
}
}
Expand Down
41 changes: 41 additions & 0 deletions pkg/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -204,6 +204,46 @@ type RemoteServer struct {
Links []*OtherLink
}

type AutotestCustomActionEnvType string

const (
AutotestCustomActionEnvList AutotestCustomActionEnvType = "list"
AutotestCustomActionEnvText AutotestCustomActionEnvType = "text"
)

type AutotestCustomActionEnv struct {
Name string
Default string
Description string
Type AutotestCustomActionEnvType
}

type AutotestCustomAction struct {
ProjectID int
Tests []string
Env []*AutotestCustomActionEnv
}

func (d *AutotestCustomAction) DeepCopy() *AutotestCustomAction {
copyOfCustomAction := AutotestCustomAction{}

if d == nil {
return &copyOfCustomAction
}

typeJSON, err := json.Marshal(d)
if err != nil {
log.WithError(err).Fatal("error while json.Marshal")
}

err = json.Unmarshal(typeJSON, &copyOfCustomAction)
if err != nil {
log.WithError(err).Fatal("error while json.Unmarshal")
}

return &copyOfCustomAction
}

type AutotestAction struct {
Name string
Test string
Expand All @@ -215,6 +255,7 @@ type Autotest struct {
ProjectID int
ReportURL string
Actions []*AutotestAction
CustomAction *AutotestCustomAction
FilterByNamespace bool
}

Expand Down
113 changes: 83 additions & 30 deletions pkg/modules/autotests/autotests.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ type (
Test string
}
Details struct {
CustomAction *config.AutotestCustomAction
Actions []*config.AutotestAction
Pipelines []*Pipeline
LastPipelines []*Pipeline
Expand Down Expand Up @@ -76,6 +77,14 @@ const (
defaultGetAutotestDetailsSize = 10
)

func (d *Details) Normalize(a *config.Autotest) error {
if d.CustomAction.ProjectID == 0 {
d.CustomAction.ProjectID = a.ProjectID
}

return nil
}

func GetAutotestDetails(ctx context.Context, environment *api.Environment, size int) (*Details, error) {
autotestConfig := config.Get().GetAutotestByID(environment.ID)

Expand All @@ -84,11 +93,17 @@ func GetAutotestDetails(ctx context.Context, environment *api.Environment, size
}

result := Details{
CustomAction: autotestConfig.CustomAction.DeepCopy(),
Actions: autotestConfig.Actions,
Pipelines: []*Pipeline{},
LastPipelines: []*Pipeline{},
}

// add defaults values if not set
if err := result.Normalize(autotestConfig); err != nil {
return nil, errors.Wrap(err, "error normalizing")
}

gitlabClient := client.GetGitlabClient()

pipelines, _, err := gitlabClient.Pipelines.ListProjectPipelines(
Expand Down Expand Up @@ -188,55 +203,76 @@ func GetAutotestDetails(ctx context.Context, environment *api.Environment, size
return &result, nil
}

func StartAutotest(ctx context.Context, environment *api.Environment, test string, user string) error {
autotestConfig := config.Get().GetAutotestByID(environment.ID)
type StartAutotestInput struct {
environment *api.Environment
Ref string
Test string
User string
ExtraEnv map[string]string
}

func (s *StartAutotestInput) Validate() error {
if len(s.Test) == 0 {
return errors.New("test type is empty")
}

if len(s.User) == 0 {
return errors.New("user is empty")
}

if s.environment == nil {
return errors.New("environment is empty")
}

return nil
}

func (s *StartAutotestInput) SetEnvironment(environment *api.Environment) {
s.environment = environment
}

func StartAutotest(ctx context.Context, input *StartAutotestInput) error {
if err := input.Validate(); err != nil {
return errors.Wrap(err, "error validating input")
}

autotestConfig := config.Get().GetAutotestByID(input.environment.ID)

if autotestConfig == nil {
return errNotFound
}

action := autotestConfig.GetActionByTest(test)
action := autotestConfig.GetActionByTest(input.Test)

if action == nil {
return errNotFound
}

if len(input.Ref) == 0 {
input.Ref = action.Ref
}

// check for pending pipelines
details, err := GetAutotestDetails(ctx, environment, defaultGetAutotestDetailsSize)
details, err := GetAutotestDetails(ctx, input.environment, defaultGetAutotestDetailsSize)
if err != nil {
return errors.Wrap(err, "error getting environment details")
}

for _, pipeline := range details.Pipelines {
if pipeline.Test == test && (pipeline.Status == pipelineStatusRunning || pipeline.Status == pipelineStatusPending) {
if pipeline.Test == input.Test &&
(pipeline.Status == pipelineStatusRunning || pipeline.Status == pipelineStatusPending) {
return errPipelineIsRunning
}
}

gitlabClient := client.GetGitlabClient()

variables := make([]*gitlab.PipelineVariableOptions, 0)

variables = append(variables, &gitlab.PipelineVariableOptions{
Key: gitlab.String(envNameTest),
Value: gitlab.String(test),
VariableType: gitlab.String("env_var"),
})

variables = append(variables, &gitlab.PipelineVariableOptions{
Key: gitlab.String(envNameOwner),
Value: gitlab.String(user),
VariableType: gitlab.String("env_var"),
})

variables = append(variables, &gitlab.PipelineVariableOptions{
Key: gitlab.String(envNameNamespace),
Value: gitlab.String(environment.Namespace),
VariableType: gitlab.String("env_var"),
})
pipelineEnv := map[string]string{
envNameTest: input.Test,
envNameOwner: input.User,
envNameNamespace: input.environment.Namespace,
}

if len(action.Release) > 0 {
releaseURL, err := utils.GetTemplatedResult(action.Release, environment)
releaseURL, err := utils.GetTemplatedResult(action.Release, input.environment)
if err != nil {
return errors.Wrap(err, "error getting release url")
}
Expand All @@ -246,17 +282,34 @@ func StartAutotest(ctx context.Context, environment *api.Environment, test strin
return errors.Wrap(err, "error getting release name")
}

pipelineEnv[envNameRelease] = release
}

// add extra env
for key, value := range input.ExtraEnv {
pipelineEnv[key] = value
}

gitlabClient := client.GetGitlabClient()

variables := make([]*gitlab.PipelineVariableOptions, 0)

for key, value := range pipelineEnv {
if len(value) == 0 {
return errors.Errorf("env %s is empty", key)
}

variables = append(variables, &gitlab.PipelineVariableOptions{
Key: gitlab.String(envNameRelease),
Value: gitlab.String(release),
Key: gitlab.String(key),
Value: gitlab.String(value),
VariableType: gitlab.String("env_var"),
})
}

_, _, err = gitlabClient.Pipelines.CreatePipeline(
autotestConfig.ProjectID,
&gitlab.CreatePipelineOptions{
Ref: &action.Ref,
Ref: &input.Ref,
Variables: &variables,
},
gitlab.WithContext(ctx),
Expand Down
13 changes: 6 additions & 7 deletions pkg/web/handlerEnvironment.go
Original file line number Diff line number Diff line change
Expand Up @@ -675,20 +675,19 @@ func environmentOperation(ctx context.Context, r *http.Request, environmentID st
}

result.Result = autotestsResults
case "make-start-autotest":
type StartAutotest struct {
Test string
User string
case "make-start-autotest", "make-start-autotest-custom":
startAutotest := autotests.StartAutotestInput{
User: owner[0],
}

startAutotest := StartAutotest{}

err = json.Unmarshal(body, &startAutotest)
if err != nil {
return result, err
}

err = autotests.StartAutotest(ctx, environment, startAutotest.Test, startAutotest.User)
startAutotest.SetEnvironment(environment)

err = autotests.StartAutotest(ctx, &startAutotest)
if err != nil {
return result, err
}
Expand Down

0 comments on commit c46759d

Please sign in to comment.