diff --git a/pipeline/frontend/yaml/compiler/convert.go b/pipeline/frontend/yaml/compiler/convert.go index 5ff01b99e..37d899e01 100644 --- a/pipeline/frontend/yaml/compiler/convert.go +++ b/pipeline/frontend/yaml/compiler/convert.go @@ -134,11 +134,10 @@ func (c *Compiler) createProcess(name string, container *yaml.Container, section cpuSet = c.reslimit.CPUSet } - // all constraints must exclude success. - onSuccess := container.When.IsEmpty() || - !container.When.ExcludesStatus("success") + // at least one constraint contain status success, or all constraints have no status set + onSuccess := container.When.IncludesStatusSuccess() // at least one constraint must include the status failure. - onFailure := container.When.IncludesStatus("failure") + onFailure := container.When.IncludesStatusFailure() failure := container.Failure if container.Failure == "" { diff --git a/pipeline/frontend/yaml/constraint/constraint.go b/pipeline/frontend/yaml/constraint/constraint.go index 2557e0e13..6db26f69b 100644 --- a/pipeline/frontend/yaml/constraint/constraint.go +++ b/pipeline/frontend/yaml/constraint/constraint.go @@ -79,9 +79,9 @@ func (when *When) Match(metadata frontend.Metadata, global bool) (bool, error) { return false, nil } -func (when *When) IncludesStatus(status string) bool { +func (when *When) IncludesStatusFailure() bool { for _, c := range when.Constraints { - if c.Status.Includes(status) { + if c.Status.Includes("failure") { return true } } @@ -89,14 +89,19 @@ func (when *When) IncludesStatus(status string) bool { return false } -func (when *When) ExcludesStatus(status string) bool { +func (when *When) IncludesStatusSuccess() bool { + // "success" acts differently than "failure" in that it's + // presumed to be included unless it's specifically not part + // of the list + if when.IsEmpty() { + return true + } for _, c := range when.Constraints { - if !c.Status.Excludes(status) { - return false + if len(c.Status.Include) == 0 || c.Status.Includes("success") { + return true } } - - return len(when.Constraints) > 0 + return false } // False if (any) non local diff --git a/pipeline/frontend/yaml/constraint/constraint_test.go b/pipeline/frontend/yaml/constraint/constraint_test.go index f5fec49be..3c72f59b0 100644 --- a/pipeline/frontend/yaml/constraint/constraint_test.go +++ b/pipeline/frontend/yaml/constraint/constraint_test.go @@ -381,6 +381,24 @@ func TestConstraintMap(t *testing.T) { } } +func TestConstraintStatusSuccess(t *testing.T) { + testdata := []struct { + conf string + want bool + }{ + {conf: "", want: true}, + {conf: "{status: [failure]}", want: false}, + {conf: "{status: [success]}", want: true}, + {conf: "{status: [failure, success]}", want: true}, + {conf: "{status: {exclude: [success], include: [failure]}}", want: false}, + {conf: "{status: {exclude: [failure], include: [success]}}", want: true}, + } + for _, test := range testdata { + c := parseConstraints(t, test.conf) + assert.Equal(t, test.want, c.IncludesStatusSuccess(), "when: '%s'", test.conf) + } +} + func TestConstraints(t *testing.T) { testdata := []struct { desc string