Skip to content

Commit

Permalink
accessor for step error in templating values (#16)
Browse files Browse the repository at this point in the history
Signed-off-by: Pablo Pérez Schröder <[email protected]>
  • Loading branch information
pablito-perez authored Nov 12, 2019
1 parent 8996ecc commit d17e668
Show file tree
Hide file tree
Showing 7 changed files with 39 additions and 5 deletions.
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,8 @@ A user can be allowed to resolve a task in three ways:
- `.resolver_input.[INPUT_NAME]`: the value of an input provided by the task's resolver
- `.step.[STEP_NAME].output.foo`: field `foo` from the output of a named step
- `.step.[STEP_NAME].metadata.HTTPStatus`: field `HTTPStatus` from the metadata of a named step
- `.step.[STEP_NAME].children`: the collection of results from a 'foreach' step
- `.step.[STEP_NAME].error`: error message from a failed step
- `.config.[CONFIG_ITEM].bar`: field `bar` from a config item (configstore, see above)
- `.iterator.foo`: field `foo` from the iterator in a loop (see `foreach` steps below)

Expand Down
1 change: 1 addition & 0 deletions engine/engine.go
Original file line number Diff line number Diff line change
Expand Up @@ -348,6 +348,7 @@ func resolve(dbp zesty.DBProvider, res *resolution.Resolution, t *task.Task, deb
res.Values.SetOutput(s.Name, s.Output)
res.Values.SetMetadata(s.Name, s.Metadata)
res.Values.SetChildren(s.Name, s.Children)
res.Values.SetError(s.Name, s.Error)

// call after-run step logic
modifiedSteps := map[string]bool{
Expand Down
5 changes: 4 additions & 1 deletion engine/engine_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -162,9 +162,12 @@ func TestSimpleTemplate(t *testing.T) {
res, err := runTask("simple.yaml", input, nil)

assert.Equal(t, nil, err)
assert.Equal(t, resolution.StateDone, res.State)
assert.Equal(t, resolution.StateError, res.State)
assert.Equal(t, step.StateDone, res.Steps["stepOne"].State)
assert.Equal(t, step.StateDone, res.Steps["stepTwo"].State)
assert.Equal(t, step.StateServerError, res.Steps["stepThree"].State)

assert.Equal(t, "FAIL!", res.Values.GetError("stepThree"))
}

func TestClientError(t *testing.T) {
Expand Down
6 changes: 3 additions & 3 deletions engine/step/condition.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ const (
LT = "LT"
GE = "GE"
LE = "LE"
REGEXP = "regexp"
REGEXP = "REGEXP"
)

type (
Expand Down Expand Up @@ -51,7 +51,7 @@ func (a *Assert) Eval(v *values.Values, item interface{}, stepName string) error
valStr := strings.Replace(string(val), "<no value>", "", -1)
expStr := strings.Replace(string(expected), "<no value>", "", -1)

switch a.Operator {
switch strings.ToUpper(a.Operator) { // normalized operator, accept both lower case and upper case from template
case EQ:
if valStr != expStr {
return ErrConditionNotMet(fmt.Sprintf("Condition not met: expected '%s', got '%s': %s", expStr, valStr, a.Message))
Expand Down Expand Up @@ -100,7 +100,7 @@ func (a *Assert) Eval(v *values.Values, item interface{}, stepName string) error
// ie. the operator is among the accepted values listed above
func (a *Assert) Valid() error {
if a != nil {
switch a.Operator {
switch strings.ToUpper(a.Operator) {
case EQ, NE, GT, LT, GE, LE:
case REGEXP:
if _, err := regexp.Compile(a.Expected); err != nil {
Expand Down
8 changes: 8 additions & 0 deletions engine/templates_tests/simple.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -17,3 +17,11 @@ steps:
configuration:
output:
foo: baz
stepThree:
description: third step, fails
dependencies: [stepTwo]
action:
type: echo
configuration:
error_message: FAIL!

21 changes: 20 additions & 1 deletion engine/values/values.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@ import (

"github.com/Masterminds/sprig"
"github.com/juju/errors"
"github.com/robertkrimen/otto"
"github.com/ovh/utask"
"github.com/robertkrimen/otto"
)

// keys to store/retrieve data from a Values struct
Expand All @@ -26,6 +26,7 @@ const (
OutputKey = "output"
MetadataKey = "metadata"
ChildrenKey = "children"
ErrorKey = "error"
)

// Values is a container for all the live data of a running task
Expand Down Expand Up @@ -124,6 +125,21 @@ func (v *Values) UnsetChildren(stepName string) {
v.unsetStepData(stepName, ChildrenKey)
}

// GetError returns the error resulting from a failed step
func (v *Values) GetError(stepName string) interface{} {
return v.getStepData(stepName, ErrorKey)
}

// SetChildren stores the error resulting from a failed step
func (v *Values) SetError(stepName string, value interface{}) {
v.setStepData(stepName, ErrorKey, value)
}

// UnsetChildren empties the error from a failed step
func (v *Values) UnsetError(stepName string) {
v.unsetStepData(stepName, ErrorKey)
}

func (v *Values) getStepData(stepName, field string) interface{} {
stepmap := v.m[StepKey].(map[string]interface{})
if stepmap[stepName] == nil {
Expand Down Expand Up @@ -213,6 +229,9 @@ func (v *Values) Apply(templateStr string, item interface{}, stepName string) ([

v.SetChildren(utask.This, v.GetChildren(stepName))
defer v.UnsetChildren(utask.This)

v.SetError(utask.This, v.GetError(stepName))
defer v.UnsetError(utask.This)
}

err = tmpl.Execute(b, v.m)
Expand Down
1 change: 1 addition & 0 deletions models/resolution/resolution.go
Original file line number Diff line number Diff line change
Expand Up @@ -460,6 +460,7 @@ func (r *Resolution) setSteps(st map[string]*step.Step) {
r.Values.SetOutput(name, s.Output)
r.Values.SetMetadata(name, s.Metadata)
r.Values.SetChildren(name, s.Children)
r.Values.SetError(s.Name, s.Error)
}
}

Expand Down

0 comments on commit d17e668

Please sign in to comment.