1
0
mirror of https://github.com/SAP/jenkins-library.git synced 2024-12-12 10:55:20 +02:00

unify mocking for shell and exec runner (#1120)

* same behaviour for shellRunner and execRunner wrt errors and stdout

* replace shouldFail with shouldFailOnCommand

* [formatting only] format struct

* Move to regex for execptions and stdout

* shrink code
This commit is contained in:
Marcus Holl 2020-02-21 10:56:53 +01:00 committed by GitHub
parent 38237eb97b
commit d04edd5e8d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 75 additions and 27 deletions

View File

@ -24,7 +24,7 @@ func TestRunDetect(t *testing.T) {
var hasFailed bool
log.Entry().Logger.ExitFunc = func(int) { hasFailed = true }
s := shellMockRunner{shouldFailWith: fmt.Errorf("Test Error")}
s := shellMockRunner{shouldFailOnCommand: map[string]error{"bash <(curl -s https://detect.synopsys.com/detect.sh) --blackduck.url= --blackduck.api.token= --detect.project.name= --detect.project.version.name= --detect.code.location.name=": fmt.Errorf("Test Error")}}
runDetect(detectExecuteScanOptions{}, &s)
assert.True(t, hasFailed, "expected command to exit with fatal")
})

View File

@ -29,7 +29,7 @@ func TestRunKarma(t *testing.T) {
opts := karmaExecuteTestsOptions{ModulePath: "./test", InstallCommand: "fail install test", RunCommand: "npm run test"}
e := execMockRunner{shouldFailWith: errors.New("error case")}
e := execMockRunner{shouldFailOnCommand: map[string]error{"fail install test": errors.New("error case")}}
runKarma(opts, &e)
assert.True(t, hasFailed, "expected command to exit with fatal")
})
@ -40,7 +40,7 @@ func TestRunKarma(t *testing.T) {
opts := karmaExecuteTestsOptions{ModulePath: "./test", InstallCommand: "npm install test", RunCommand: "npm run test"}
e := execMockRunner{shouldFailWith: errors.New("error case")}
e := execMockRunner{shouldFailOnCommand: map[string]error{"npm install test": errors.New("error case")}}
runKarma(opts, &e)
assert.True(t, hasFailed, "expected command to exit with fatal")
})

View File

@ -6,6 +6,7 @@ import (
"io/ioutil"
"os"
"path/filepath"
"regexp"
"strings"
"testing"
@ -22,7 +23,6 @@ type execMockRunner struct {
stdout io.Writer
stderr io.Writer
stdoutReturn map[string]string
shouldFailWith error
shouldFailOnCommand map[string]error
}
@ -32,13 +32,14 @@ type execCall struct {
}
type shellMockRunner struct {
dir string
env [][]string
calls []string
shell []string
stdout io.Writer
stderr io.Writer
shouldFailWith error
dir string
env [][]string
calls []string
shell []string
stdout io.Writer
stderr io.Writer
stdoutReturn map[string]string
shouldFailOnCommand map[string]error
}
func (m *execMockRunner) Dir(d string) {
@ -50,22 +51,13 @@ func (m *execMockRunner) Env(e []string) {
}
func (m *execMockRunner) RunExecutable(e string, p ...string) error {
if m.shouldFailWith != nil {
return m.shouldFailWith
}
exec := execCall{exec: e, params: p}
m.calls = append(m.calls, exec)
if c := strings.Join(append([]string{e}, p...), " "); m.shouldFailOnCommand != nil && m.shouldFailOnCommand[c] != nil {
return m.shouldFailOnCommand[c]
}
c := strings.Join(append([]string{e}, p...), " ")
if c := strings.Join(append([]string{e}, p...), " "); m.stdoutReturn != nil && len(m.stdoutReturn[c]) > 0 {
m.stdout.Write([]byte(m.stdoutReturn[c]))
}
return nil
return handleCall(c, m.stdoutReturn, m.shouldFailOnCommand, m.stdout)
}
func (m *execMockRunner) Stdout(out io.Writer) {
@ -86,11 +78,67 @@ func (m *shellMockRunner) Env(e []string) {
func (m *shellMockRunner) RunShell(s string, c string) error {
if m.shouldFailWith != nil {
return m.shouldFailWith
}
m.shell = append(m.shell, s)
m.calls = append(m.calls, c)
return handleCall(c, m.stdoutReturn, m.shouldFailOnCommand, m.stdout)
}
func handleCall(call string, stdoutReturn map[string]string, shouldFailOnCommand map[string]error, stdout io.Writer) error {
if stdoutReturn != nil {
for k, v := range stdoutReturn {
found := k == call
if !found {
r, e := regexp.Compile(k)
if e != nil {
return e
// we don't distinguish here between an error returned
// since it was configured or returning this error here
// indicating an invalid regex. Anyway: when running the
// test we will see it ...
}
if r.MatchString(call) {
found = true
}
}
if found {
stdout.Write([]byte(v))
}
}
}
if shouldFailOnCommand != nil {
for k, v := range shouldFailOnCommand {
found := k == call
if !found {
r, e := regexp.Compile(k)
if e != nil {
return e
// we don't distinguish here between an error returned
// since it was configured or returning this error here
// indicating an invalid regex. Anyway: when running the
// test we will see it ...
}
if r.MatchString(call) {
found = true
}
}
if found {
return v
}
}
}
return nil
}

View File

@ -148,10 +148,10 @@ func TestDeploy(t *testing.T) {
copiedFiles = nil
removedFiles = nil
s.calls = nil
s.shouldFailWith = nil
s.shouldFailOnCommand = nil
}()
s.shouldFailWith = errors.New("Error from underlying process")
s.shouldFailOnCommand = map[string]error{"#!/bin/bash\nxs login -a https://example.org:12345 -u me -p 'secretPassword' -o myOrg -s mySpace --skip-ssl-validation\n": errors.New("Error from underlying process")}
e := runXsDeploy(myXsDeployOptions, &s, fExists, fCopy, fRemove, ioutil.Discard)
checkErr(t, e, "Error from underlying process")