1
0
mirror of https://github.com/SAP/jenkins-library.git synced 2025-01-30 05:59:39 +02:00
sap-jenkins-library/pkg/command/command_test.go
Marcus Holl d3820cb1f7
Have strategy for environment variable handling only once (#1234)
Have strategy for environment variable handling only once

And provide also a test checking if the environment variables
are present in the forked process.

The strategy applied for setting the environment variables is now
different from what it was before. Before the environment was
fully replaced by the new environment variables. Now we append
our environment variables to the list of environment variables available
by default for the forked process.



Co-authored-by: Florian Geckeler <43751896+fgeckeler@users.noreply.github.com>
2020-03-03 11:15:24 +01:00

212 lines
4.9 KiB
Go

package command
import (
"bytes"
"fmt"
"io/ioutil"
"os"
"os/exec"
"strings"
"testing"
)
//based on https://golang.org/src/os/exec/exec_test.go
func helperCommand(command string, s ...string) (cmd *exec.Cmd) {
cs := []string{"-test.run=TestHelperProcess", "--", command}
cs = append(cs, s...)
cmd = exec.Command(os.Args[0], cs...)
cmd.Env = []string{"GO_WANT_HELPER_PROCESS=1"}
return cmd
}
func TestShellRun(t *testing.T) {
t.Run("test shell", func(t *testing.T) {
ExecCommand = helperCommand
defer func() { ExecCommand = exec.Command }()
o := new(bytes.Buffer)
e := new(bytes.Buffer)
s := Command{stdout: o, stderr: e}
s.RunShell("/bin/bash", "myScript")
t.Run("success case", func(t *testing.T) {
t.Run("stdin-stdout", func(t *testing.T) {
expectedOut := "Stdout: command /bin/bash - Stdin: myScript\n"
if oStr := o.String(); oStr != expectedOut {
t.Errorf("expected: %v got: %v", expectedOut, oStr)
}
})
t.Run("stderr", func(t *testing.T) {
expectedErr := "Stderr: command /bin/bash\n"
if eStr := e.String(); eStr != expectedErr {
t.Errorf("expected: %v got: %v", expectedErr, eStr)
}
})
})
})
}
func TestExecutableRun(t *testing.T) {
t.Run("test shell", func(t *testing.T) {
ExecCommand = helperCommand
defer func() { ExecCommand = exec.Command }()
stdout := new(bytes.Buffer)
stderr := new(bytes.Buffer)
ex := Command{stdout: stdout, stderr: stderr}
ex.RunExecutable("echo", []string{"foo bar", "baz"}...)
t.Run("success case", func(t *testing.T) {
t.Run("stdin", func(t *testing.T) {
expectedOut := "foo bar baz\n"
if oStr := stdout.String(); oStr != expectedOut {
t.Errorf("expected: %v got: %v", expectedOut, oStr)
}
})
t.Run("stderr", func(t *testing.T) {
expectedErr := "Stderr: command echo\n"
if eStr := stderr.String(); eStr != expectedErr {
t.Errorf("expected: %v got: %v", expectedErr, eStr)
}
})
})
})
}
func TestEnvironmentVariables(t *testing.T) {
ExecCommand = helperCommand
defer func() { ExecCommand = exec.Command }()
stdout := new(bytes.Buffer)
stderr := new(bytes.Buffer)
ex := Command{stdout: stdout, stderr: stderr}
// helperCommand function replaces the full environment with one single entry
// (GO_WANT_HELPER_PROCESS), hence there is no need for checking if the DEBUG
// environment variable already exists in the set of environment variables for the
// current process.
ex.SetEnv([]string{"DEBUG=true"})
ex.RunExecutable("env")
oStr := stdout.String()
if !strings.Contains(oStr, "DEBUG=true") {
t.Errorf("expected Environment variable not found")
}
}
func TestPrepareOut(t *testing.T) {
t.Run("os", func(t *testing.T) {
s := Command{}
_out, _err := prepareOut(s.stdout, s.stderr)
if _out != os.Stdout {
t.Errorf("expected out to be os.Stdout")
}
if _err != os.Stderr {
t.Errorf("expected err to be os.Stderr")
}
})
t.Run("custom", func(t *testing.T) {
o := bytes.NewBufferString("")
e := bytes.NewBufferString("")
s := Command{stdout: o, stderr: e}
_out, _err := prepareOut(s.stdout, s.stderr)
expectOut := "Test out"
expectErr := "Test err"
_out.Write([]byte(expectOut))
_err.Write([]byte(expectErr))
t.Run("out", func(t *testing.T) {
if o.String() != expectOut {
t.Errorf("expected: %v got: %v", expectOut, o.String())
}
})
t.Run("err", func(t *testing.T) {
if e.String() != expectErr {
t.Errorf("expected: %v got: %v", expectErr, e.String())
}
})
})
}
func TestCmdPipes(t *testing.T) {
cmd := helperCommand("echo", "foo bar", "baz")
defer func() { ExecCommand = exec.Command }()
t.Run("success case", func(t *testing.T) {
o, e, err := cmdPipes(cmd)
t.Run("no error", func(t *testing.T) {
if err != nil {
t.Errorf("error occured but no error expected")
}
})
t.Run("out pipe", func(t *testing.T) {
if o == nil {
t.Errorf("no pipe received")
}
})
t.Run("err pipe", func(t *testing.T) {
if e == nil {
t.Errorf("no pipe received")
}
})
})
}
//based on https://golang.org/src/os/exec/exec_test.go
//this is not directly executed
func TestHelperProcess(*testing.T) {
if os.Getenv("GO_WANT_HELPER_PROCESS") != "1" {
return
}
defer os.Exit(0)
args := os.Args
for len(args) > 0 {
if args[0] == "--" {
args = args[1:]
break
}
args = args[1:]
}
if len(args) == 0 {
fmt.Fprintf(os.Stderr, "No command\n")
os.Exit(2)
}
cmd, args := args[0], args[1:]
switch cmd {
case "/bin/bash":
o, _ := ioutil.ReadAll(os.Stdin)
fmt.Fprintf(os.Stdout, "Stdout: command %v - Stdin: %v\n", cmd, string(o))
fmt.Fprintf(os.Stderr, "Stderr: command %v\n", cmd)
case "echo":
iargs := []interface{}{}
for _, s := range args {
iargs = append(iargs, s)
}
fmt.Println(iargs...)
fmt.Fprintf(os.Stderr, "Stderr: command %v\n", cmd)
case "env":
for _, e := range os.Environ() {
fmt.Println(e)
}
default:
fmt.Fprintf(os.Stderr, "Unknown command %q\n", cmd)
os.Exit(2)
}
}