|
|
@@ -10,6 +10,8 @@ import ( |
|
|
"os/exec"
|
|
|
"path/filepath"
|
|
|
"runtime"
|
|
|
+ "strconv"
|
|
|
+ "strings"
|
|
|
|
|
|
gc "gopkg.in/check.v1"
|
|
|
)
|
|
|
@@ -39,15 +41,25 @@ func HookCommandOutput( |
|
|
const (
|
|
|
// EchoQuotedArgs is a simple bash script that prints out the
|
|
|
// basename of the command followed by the args as quoted strings.
|
|
|
+ // If a ; separated list of exit codes is provided in $name.exitcodes
|
|
|
+ // then it will return them in turn over multiple calls. If
|
|
|
+ // $name.exitcodes does not exist, or the list runs out, return 0.
|
|
|
EchoQuotedArgsUnix = `#!/bin/bash --norc
|
|
|
name=` + "`basename $0`" + `
|
|
|
argfile="$name.out"
|
|
|
-rm -f $argfile
|
|
|
+exitcodesfile="$name.exitcodes"
|
|
|
printf "%s" $name | tee -a $argfile
|
|
|
for arg in "$@"; do
|
|
|
printf " \"%s\"" "$arg" | tee -a $argfile
|
|
|
done
|
|
|
printf "\n" | tee -a $argfile
|
|
|
+if [ -f $exitcodesfile ]
|
|
|
+then
|
|
|
+ exitcodes=$(cat $exitcodesfile)
|
|
|
+ arr=(${exitcodes/;/ })
|
|
|
+ echo ${arr[1]} | tee $exitcodesfile
|
|
|
+ exit ${arr[0]}
|
|
|
+fi
|
|
|
`
|
|
|
EchoQuotedArgsWindows = `@echo off
|
|
|
|
|
|
@@ -58,11 +70,21 @@ for %%x in (%*) do ( |
|
|
set /A argCount+=1
|
|
|
set "argVec[!argCount!]=%%~x"
|
|
|
)
|
|
|
-
|
|
|
for /L %%i in (1,1,%argCount%) do set list=!list! "!argVec[%%i]!"
|
|
|
|
|
|
-echo %list%
|
|
|
-echo %list%> %0.out
|
|
|
+IF exist %0.exitcodes (
|
|
|
+ FOR /F "tokens=1* delims=;" %%i IN (%0.exitcodes) DO (
|
|
|
+ set exitcode=%%i
|
|
|
+ IF NOT [%%j]==[] (
|
|
|
+ echo %%j > %0.exitcodes
|
|
|
+ ) ELSE (
|
|
|
+ del %0.exitcodes
|
|
|
+ )
|
|
|
+ )
|
|
|
+)
|
|
|
+
|
|
|
+echo %list%>> %0.out
|
|
|
+exit /B %exitcode%
|
|
|
`
|
|
|
)
|
|
|
|
|
|
@@ -74,7 +96,7 @@ type EnvironmentPatcher interface { |
|
|
|
|
|
// PatchExecutable creates an executable called 'execName' in a new test
|
|
|
// directory and that directory is added to the path.
|
|
|
-func PatchExecutable(c *gc.C, patcher EnvironmentPatcher, execName, script string) {
|
|
|
+func PatchExecutable(c *gc.C, patcher CleanupPatcher, execName, script string, exitCodes ...int) {
|
|
|
dir := c.MkDir()
|
|
|
patcher.PatchEnvironment("PATH", joinPathLists(dir, os.Getenv("PATH")))
|
|
|
var filename string
|
|
|
@@ -84,8 +106,23 @@ func PatchExecutable(c *gc.C, patcher EnvironmentPatcher, execName, script strin |
|
|
default:
|
|
|
filename = filepath.Join(dir, execName)
|
|
|
}
|
|
|
- err := ioutil.WriteFile(filename, []byte(script), 0755)
|
|
|
+ os.Remove(filename + ".out")
|
|
|
+ err := ioutil.WriteFile(filename, []byte(script), 0644)
|
|
|
c.Assert(err, gc.IsNil)
|
|
|
+
|
|
|
+ if len(exitCodes) > 0 {
|
|
|
+ filename = execName + ".exitcodes"
|
|
|
+ codes := make([]string, len(exitCodes))
|
|
|
+ for i, code := range exitCodes {
|
|
|
+ codes[i] = strconv.Itoa(code)
|
|
|
+ }
|
|
|
+ s := strings.Join(codes, ";") + ";"
|
|
|
+ err = ioutil.WriteFile(filename, []byte(s), 0644)
|
|
|
+ c.Assert(err, gc.IsNil)
|
|
|
+ patcher.AddCleanup(func(*gc.C) {
|
|
|
+ os.Remove(filename)
|
|
|
+ })
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
type CleanupPatcher interface {
|
|
|
@@ -122,32 +159,37 @@ func PatchExecutableThrowError(c *gc.C, patcher CleanupPatcher, execName string, |
|
|
// test directory and that directory is added to the path. The content of the
|
|
|
// script is 'EchoQuotedArgs', and the args file is removed using a cleanup
|
|
|
// function.
|
|
|
-func PatchExecutableAsEchoArgs(c *gc.C, patcher CleanupPatcher, execName string) {
|
|
|
+func PatchExecutableAsEchoArgs(c *gc.C, patcher CleanupPatcher, execName string, exitCodes ...int) {
|
|
|
switch runtime.GOOS {
|
|
|
case "windows":
|
|
|
- PatchExecutable(c, patcher, execName, EchoQuotedArgsWindows)
|
|
|
+ PatchExecutable(c, patcher, execName, EchoQuotedArgsWindows, exitCodes...)
|
|
|
default:
|
|
|
- PatchExecutable(c, patcher, execName, EchoQuotedArgsUnix)
|
|
|
+ PatchExecutable(c, patcher, execName, EchoQuotedArgsUnix, exitCodes...)
|
|
|
}
|
|
|
patcher.AddCleanup(func(*gc.C) {
|
|
|
os.Remove(execName + ".out")
|
|
|
+ os.Remove(execName + ".exitcodes")
|
|
|
})
|
|
|
}
|
|
|
|
|
|
// AssertEchoArgs is used to check the args from an execution of a command
|
|
|
// that has been patchec using PatchExecutable containing EchoQuotedArgs.
|
|
|
func AssertEchoArgs(c *gc.C, execName string, args ...string) {
|
|
|
+ // Read in entire argument log file
|
|
|
content, err := ioutil.ReadFile(execName + ".out")
|
|
|
c.Assert(err, gc.IsNil)
|
|
|
+ lines := strings.Split(string(content), "\n")
|
|
|
+
|
|
|
+ // Create expected output string
|
|
|
expected := execName
|
|
|
for _, arg := range args {
|
|
|
expected = fmt.Sprintf("%s %q", expected, arg)
|
|
|
}
|
|
|
- switch runtime.GOOS {
|
|
|
- case "windows":
|
|
|
- expected += "\r\n"
|
|
|
- default:
|
|
|
- expected += "\n"
|
|
|
- }
|
|
|
- c.Assert(string(content), gc.Equals, expected)
|
|
|
+
|
|
|
+ // Check that the expected and the first line of actual output are the same
|
|
|
+ c.Assert(lines[0], gc.Equals, expected)
|
|
|
+
|
|
|
+ // Write out the remaining lines for the next check
|
|
|
+ content = []byte(strings.Join(lines[1:], "\n"))
|
|
|
+ err = ioutil.WriteFile(execName+".out", content, 0644) // or just call this filename somewhere, once.
|
|
|
}
|