Skip to content

Commit

Permalink
fix(venom): re-templating vars (#161)
Browse files Browse the repository at this point in the history
  • Loading branch information
yesnault authored and fsamin committed Aug 8, 2018
1 parent ed86662 commit b188839
Show file tree
Hide file tree
Showing 6 changed files with 67 additions and 18 deletions.
4 changes: 2 additions & 2 deletions process_files.go
Original file line number Diff line number Diff line change
Expand Up @@ -80,9 +80,9 @@ func (v *Venom) readFiles(filesPath []string) (err error) {

// Apply templater unitl there is no more modifications
// it permits to include testcase from env
out := ts.Templater.apply(dat)
_, out := ts.Templater.apply(dat)
for i := 0; i < 10; i++ {
tmp := ts.Templater.apply(out)
_, tmp := ts.Templater.apply(out)
if string(tmp) == string(out) {
break
}
Expand Down
2 changes: 1 addition & 1 deletion process_testcase.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import (

func (v *Venom) initTestCaseContext(ts *TestSuite, tc *TestCase) (TestCaseContext, error) {
var errContext error
tc.Context, errContext = ts.Templater.ApplyOnContext(tc.Context)
_, tc.Context, errContext = ts.Templater.ApplyOnMap(tc.Context)
if errContext != nil {
return nil, errContext
}
Expand Down
17 changes: 17 additions & 0 deletions process_teststep.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@ import (
"context"
"fmt"
"time"

dump "github.com/fsamin/go-dump"
log "github.com/sirupsen/logrus"
)

//RunTestStep executes a venom testcase is a venom context
Expand Down Expand Up @@ -38,6 +41,20 @@ func (v *Venom) RunTestStep(tcc TestCaseContext, e *ExecutorWrap, ts *TestSuite,
// add result again for extracts values
ts.Templater.Add(tc.Name, stringifyExecutorResult(result))

// then template the TestSuite vars if needed
var applied bool
applied, ts.Vars, err = ts.Templater.ApplyOnMap(ts.Vars)
if err != nil {
log.Errorf("err:%s", err)
}
if applied {
d, err := dump.ToStringMap(ts.Vars)
if err != nil {
log.Errorf("err:%s", err)
}
ts.Templater.Add("", d)
}

if assertRes.ok {
break
}
Expand Down
32 changes: 18 additions & 14 deletions templater.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ func (tmpl *Templater) ApplyOnStep(stepNumber int, step TestStep) (TestStep, err
if stepNumber >= 0 {
tmpl.Add("", map[string]string{"venom.teststep.number": fmt.Sprintf("%d", stepNumber)})
}
sb = tmpl.apply(s)
_, sb = tmpl.apply(s)
}

var t TestStep
Expand All @@ -61,47 +61,51 @@ func (tmpl *Templater) ApplyOnStep(stepNumber int, step TestStep) (TestStep, err
return t, nil
}

//ApplyOnContext executes the template on a context
func (tmpl *Templater) ApplyOnContext(ctx map[string]interface{}) (map[string]interface{}, error) {
//ApplyOnMap executes the template on a context
// return true if there is an variable replaced
func (tmpl *Templater) ApplyOnMap(mapStringInterface map[string]interface{}) (bool, map[string]interface{}, error) {
var t map[string]interface{}
if len(ctx) == 0 {
return t, nil
if len(mapStringInterface) == 0 {
return false, t, nil
}

// Using yaml to encode/decode, it generates map[interface{}]interface{} typed data that json does not like
s, err := yaml.Marshal(ctx)
s, err := yaml.Marshal(mapStringInterface)
if err != nil {
return nil, fmt.Errorf("templater> Error while marshaling: %s", err)
return false, nil, fmt.Errorf("templater> Error while marshaling: %s", err)
}
sb := s
// if the context use some variable, we run tmpl.apply on it
var applied bool
// if the mapStringInterface use some variable, we run tmpl.apply on it
if strings.Contains(string(s), "{{") {
sb = tmpl.apply(s)
applied, sb = tmpl.apply(s)
}

if err := yaml.Unmarshal([]byte(sb), &t); err != nil {
return nil, fmt.Errorf("templater> Error while unmarshal: %s, content:%s", err, sb)
return applied, nil, fmt.Errorf("templater> Error while unmarshal: %s, content:%s", err, sb)
}

return t, nil
return applied, t, nil
}

func (tmpl *Templater) apply(in []byte) []byte {
func (tmpl *Templater) apply(in []byte) (bool, []byte) {
tmpl.Add("", map[string]string{
"venom.datetime": time.Now().Format(time.RFC3339),
"venom.timestamp": fmt.Sprintf("%d", time.Now().Unix()),
})
var applied bool
out := string(in)
for k, v := range tmpl.Values {
applied = true
var buffer bytes.Buffer
buffer.WriteString("{{.")
buffer.WriteString(k)
buffer.WriteString("}}")
out = strings.Replace(out, buffer.String(), v, -1)
// if no more variable to replace, exit
if !strings.Contains(out, "{{") {
return []byte(out)
return applied, []byte(out)
}
}
return []byte(out)
return applied, []byte(out)
}
25 changes: 25 additions & 0 deletions tests/TestVars.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
name: testVars

vars:
service.id: '{{.CreateService.id}}'
thevar: 'thevalue'

testcases:

- name: CreateService
steps:
- type: exec
script: echo 'foo with a bar here'
assertions:
- result.code ShouldEqual 0
- result.timeseconds ShouldBeLessThan 1
extracts:
result.systemout: foo with a {{id=[a-z]+}} here

- name: WriteServiceIdForNextTestSuites
steps:
- script: "echo 'value:{{.service.id}} - end value'"
assertions:
- result.code ShouldEqual 0
- result.systemout ShouldContainSubstring bar

5 changes: 4 additions & 1 deletion venom_output.go
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,10 @@ func (v *Venom) OutputResult(tests Tests, elapsed time.Duration) error {
dumpEncoder.Fdump(f.Result)
}

output := f.Value + "\n ------ \n" + sdump.String()
output := f.Value + "\n ------ Result: \n" + sdump.String() + "\n ------ Variables:\n"
for k, v := range ts.Templater.Values {
output += fmt.Sprintf("%s:%s\n", k, v)
}
if err := ioutil.WriteFile(filename, []byte(output), 0644); err != nil {
return fmt.Errorf("Error while creating file %s: %v", filename, err)
}
Expand Down

0 comments on commit b188839

Please sign in to comment.