diff --git a/pipeline/container.go b/pipeline/container.go index 835bf651..f5428015 100644 --- a/pipeline/container.go +++ b/pipeline/container.go @@ -117,3 +117,42 @@ func (c *ContainerSlice) Sanitize(driver string) *ContainerSlice { return nil } } + +// Execute returns true when the provided ruledata matches +// the conditions when we should be running the container on the worker. +func (c *Container) Execute(r *RuleData) bool { + // assume you will execute the container + execute := true + + // capture the build status out of the ruleset + status := r.Status + + // check if the build status is successful + if !strings.EqualFold(status, constants.StatusSuccess) { + // disregard the need to run the container + execute = false + + // check if you need to run a status failure ruleset + if !(c.Ruleset.If.Empty() && c.Ruleset.Unless.Empty()) && + c.Ruleset.Match(r) { + // approve the need to run the container + execute = true + } + } + + r.Status = constants.StatusFailure + + // check if you need to skip a status failure ruleset + if strings.EqualFold(status, constants.StatusSuccess) && + !(c.Ruleset.If.Empty() && c.Ruleset.Unless.Empty()) && c.Ruleset.Match(r) { + + r.Status = constants.StatusSuccess + + if !c.Ruleset.Match(r) { + // disregard the need to run the container + execute = false + } + } + + return execute +} diff --git a/pipeline/container_test.go b/pipeline/container_test.go index f61da623..17cbda22 100644 --- a/pipeline/container_test.go +++ b/pipeline/container_test.go @@ -104,6 +104,257 @@ func TestPipeline_ContainerSlice_Sanitize(t *testing.T) { } } +func TestPipeline_Container_Execute(t *testing.T) { + // setup types + containers := testContainers() + *containers = (*containers)[:len(*containers)-1] + + // setup tests + tests := []struct { + container *Container + ruleData *RuleData + want bool + }{ + { // empty container with build success + container: &Container{ + Name: "empty", + Image: "alpine:latest", + Commands: []string{"echo \"Hey Vela\""}, + }, + ruleData: &RuleData{ + Branch: "master", + Event: "push", + Repo: "foo/bar", + Status: "success", + }, + want: true, + }, + { // empty container with build failure + container: &Container{ + Name: "empty", + Image: "alpine:latest", + Commands: []string{"echo \"Hey Vela\""}, + }, + ruleData: &RuleData{ + Branch: "master", + Event: "push", + Repo: "foo/bar", + Status: "failure", + }, + want: false, + }, + { // status success container with build success + container: &Container{ + Name: "status success", + Image: "alpine:latest", + Commands: []string{"echo \"Hey Vela\""}, + Ruleset: Ruleset{ + If: Rules{ + Status: []string{constants.StatusSuccess}, + }, + }, + }, + ruleData: &RuleData{ + Branch: "master", + Event: "push", + Repo: "foo/bar", + Status: "success", + }, + want: true, + }, + { // status success container with build failure + container: &Container{ + Name: "status success", + Image: "alpine:latest", + Commands: []string{"echo \"Hey Vela\""}, + Ruleset: Ruleset{ + If: Rules{ + Status: []string{constants.StatusSuccess}, + }, + }, + }, + ruleData: &RuleData{ + Branch: "master", + Event: "push", + Repo: "foo/bar", + Status: "failure", + }, + want: false, + }, + { // status/failure success container with build failure + container: &Container{ + Name: "status/failure", + Image: "alpine:latest", + Commands: []string{"echo \"Hey Vela\""}, + Ruleset: Ruleset{ + If: Rules{ + Status: []string{constants.StatusSuccess, constants.StatusFailure}, + }, + }, + }, + ruleData: &RuleData{ + Branch: "master", + Event: "push", + Repo: "foo/bar", + Status: "success", + }, + want: true, + }, + { // status/failure success container with build failure + container: &Container{ + Name: "status/failure", + Image: "alpine:latest", + Commands: []string{"echo \"Hey Vela\""}, + Ruleset: Ruleset{ + If: Rules{ + Status: []string{constants.StatusSuccess, constants.StatusFailure}, + }, + }, + }, + ruleData: &RuleData{ + Branch: "master", + Event: "push", + Repo: "foo/bar", + Status: "failure", + }, + want: true, + }, + { // branch/event/status container with build success + container: &Container{ + Name: "branch/event/status", + Image: "alpine:latest", + Commands: []string{"echo \"Hey Vela\""}, + Ruleset: Ruleset{ + If: Rules{ + Branch: []string{"master"}, + Event: []string{constants.EventPush}, + Status: []string{constants.StatusSuccess}, + }, + }, + }, + ruleData: &RuleData{ + Branch: "master", + Event: "push", + Repo: "foo/bar", + Status: "success", + }, + want: true, + }, + { // branch/event/status container with build failure + container: &Container{ + Name: "branch/event/status", + Image: "alpine:latest", + Commands: []string{"echo \"Hey Vela\""}, + Ruleset: Ruleset{ + If: Rules{ + Branch: []string{"master"}, + Event: []string{constants.EventPush}, + Status: []string{constants.StatusSuccess}, + }, + }, + }, + ruleData: &RuleData{ + Branch: "master", + Event: "push", + Repo: "foo/bar", + Status: "failure", + }, + want: false, + }, + { // branch/event/status container with build failure + container: &Container{ + Name: "branch/event/status", + Image: "alpine:latest", + Commands: []string{"echo \"Hey Vela\""}, + Ruleset: Ruleset{ + If: Rules{ + Branch: []string{"master"}, + Event: []string{constants.EventPush}, + Status: []string{constants.StatusSuccess}, + }, + Operator: "or", + }, + }, + ruleData: &RuleData{ + Branch: "master", + Event: "push", + Repo: "foo/bar", + Status: "failure", + }, + want: true, + }, + { // tag/event/status container with build success + container: &Container{ + Name: "tag/event/status", + Image: "alpine:latest", + Commands: []string{"echo \"Hey Vela\""}, + Ruleset: Ruleset{ + If: Rules{ + Tag: []string{"v0.1.0"}, + Event: []string{constants.EventTag}, + Status: []string{constants.StatusSuccess}, + }, + }, + }, + ruleData: &RuleData{ + Branch: "master", + Event: "tag", + Repo: "foo/bar", + Status: "success", + Tag: "v*", + }, + want: true, + }, + { // status unless success container with build success + container: &Container{ + Name: "status unless", + Image: "alpine:latest", + Commands: []string{"echo \"Hey Vela\""}, + Ruleset: Ruleset{ + Unless: Rules{ + Status: []string{constants.StatusSuccess}, + }, + }, + }, + ruleData: &RuleData{ + Branch: "master", + Event: "push", + Repo: "foo/bar", + Status: "success", + }, + want: false, + }, + { // status unless success container with build success + container: &Container{ + Name: "status unless", + Image: "alpine:latest", + Commands: []string{"echo \"Hey Vela\""}, + Ruleset: Ruleset{ + Unless: Rules{ + Status: []string{constants.StatusSuccess}, + }, + }, + }, + ruleData: &RuleData{ + Branch: "master", + Event: "push", + Repo: "foo/bar", + Status: "failure", + }, + want: true, + }, + } + + // run tests + for _, test := range tests { + got := test.container.Execute(test.ruleData) + + if got != test.want { + t.Errorf("Container Execute %s is %v, want %v", test.container.Name, got, test.want) + } + } +} + func testContainers() *ContainerSlice { return &ContainerSlice{ {