Multiple echo-args calls #54

Merged
merged 3 commits into from Mar 12, 2015
Jump to file or symbol
Failed to load files and symbols.
+58 −16
Split
View
74 cmd.go
@@ -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.
}