mirror of https://github.com/knative/func.git
136 lines
2.8 KiB
Go
136 lines
2.8 KiB
Go
package common
|
|
|
|
import (
|
|
"bytes"
|
|
"os"
|
|
"os/exec"
|
|
"strings"
|
|
"testing"
|
|
)
|
|
|
|
type TestExecCmd struct {
|
|
|
|
// binary to invoke
|
|
// Example: "func", "kn", "kubectl", "/usr/bin/sh"
|
|
Binary string
|
|
|
|
// Binary args to append before actual args. Examples:
|
|
// when 'kn' binary binaryArgs should be ["func"]
|
|
BinaryArgs []string
|
|
|
|
// Run commands from Dir
|
|
SourceDir string
|
|
|
|
// Indicates shell should dump command line args during execution
|
|
ShouldDumpCmdLine bool
|
|
|
|
// Indicates shell should dump
|
|
ShouldDumpOnSuccess bool
|
|
|
|
// Fail Test on Error
|
|
ShouldFailOnError bool
|
|
|
|
// Environment variable to be used with the command
|
|
Env []string
|
|
|
|
// Optional function to be used to dump stdout command results
|
|
DumpLogger func(out string)
|
|
|
|
// Access to Running or Latest command
|
|
ExecCmd *exec.Cmd
|
|
|
|
// Function to be executed while the command is running. This function is executed only once
|
|
OnWaitCallback func(stdout *bytes.Buffer)
|
|
|
|
// Function to be executed after the command is completed (before error and cmd stdout logic is executed)
|
|
OnFinishCallback func(result *TestExecCmdResult)
|
|
|
|
T *testing.T
|
|
}
|
|
|
|
// TestExecCmdResult stored command result
|
|
type TestExecCmdResult struct {
|
|
Out string
|
|
Error error
|
|
}
|
|
|
|
func (f *TestExecCmd) WithEnv(envKey string, envValue string) *TestExecCmd {
|
|
env := envKey + "=" + envValue
|
|
f.Env = append(f.Env, env)
|
|
return f
|
|
}
|
|
|
|
func (f *TestExecCmd) FromDir(dir string) *TestExecCmd {
|
|
f.SourceDir = dir
|
|
return f
|
|
}
|
|
|
|
func (f *TestExecCmd) Run(oneArgs string) TestExecCmdResult {
|
|
args := strings.Split(oneArgs, " ")
|
|
return f.Exec(args...)
|
|
}
|
|
|
|
// Exec invokes go exec library and runs a shell command combining the binary args with args from method signature
|
|
func (f *TestExecCmd) Exec(args ...string) TestExecCmdResult {
|
|
finalArgs := f.BinaryArgs
|
|
if finalArgs == nil {
|
|
finalArgs = args
|
|
} else if args != nil {
|
|
finalArgs = append(finalArgs, args...)
|
|
}
|
|
|
|
if f.ShouldDumpCmdLine {
|
|
f.T.Log(f.Binary, strings.Join(finalArgs, " "))
|
|
}
|
|
|
|
var out bytes.Buffer
|
|
|
|
cmd := exec.Command(f.Binary, finalArgs...)
|
|
cmd.Stderr = &out
|
|
cmd.Stdout = &out
|
|
f.ExecCmd = cmd
|
|
if f.SourceDir != "" {
|
|
cmd.Dir = f.SourceDir
|
|
}
|
|
cmd.Env = append(os.Environ(), f.Env...)
|
|
|
|
// Start command execution
|
|
err := cmd.Start()
|
|
if err == nil {
|
|
if f.OnWaitCallback != nil {
|
|
fn := f.OnWaitCallback
|
|
f.OnWaitCallback = nil
|
|
go fn(&out)
|
|
}
|
|
// Wait for command to complete
|
|
err = cmd.Wait()
|
|
}
|
|
|
|
result := TestExecCmdResult{
|
|
Out: out.String(),
|
|
Error: err,
|
|
}
|
|
if f.OnFinishCallback != nil {
|
|
f.OnFinishCallback(&result)
|
|
}
|
|
|
|
if err == nil && f.ShouldDumpOnSuccess {
|
|
if result.Out != "" {
|
|
if f.DumpLogger != nil {
|
|
f.DumpLogger(result.Out)
|
|
} else {
|
|
f.T.Logf("%v", result.Out)
|
|
}
|
|
}
|
|
}
|
|
if err != nil {
|
|
f.T.Log(result.Out)
|
|
f.T.Log(err.Error())
|
|
if f.ShouldFailOnError {
|
|
f.T.Fail()
|
|
}
|
|
}
|
|
|
|
return result
|
|
}
|