forked from juju/testing
/
cmd.go
96 lines (84 loc) · 2.84 KB
/
cmd.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
// Copyright 2013, 2014 Canonical Ltd.
// Licensed under the LGPLv3, see LICENCE file for details.
package testing
import (
"fmt"
"io/ioutil"
"os"
"os/exec"
"path/filepath"
gc "launchpad.net/gocheck"
)
var HookChannelSize = 10
// HookCommandOutput intercepts CommandOutput to a function that passes the
// actual command and it's output back via a channel, and returns the error
// passed into this function. It also returns a cleanup function so you can
// restore the original function
func HookCommandOutput(
outputFunc *func(cmd *exec.Cmd) ([]byte, error), output []byte, err error) (<-chan *exec.Cmd, func()) {
cmdChan := make(chan *exec.Cmd, HookChannelSize)
origCommandOutput := *outputFunc
cleanup := func() {
close(cmdChan)
*outputFunc = origCommandOutput
}
*outputFunc = func(cmd *exec.Cmd) ([]byte, error) {
cmdChan <- cmd
return output, err
}
return cmdChan, cleanup
}
const (
// EchoQuotedArgs is a simple bash script that prints out the
// basename of the command followed by the args as quoted strings.
EchoQuotedArgs = `#!/bin/bash --norc
name=` + "`basename $0`" + `
argfile="$name.out"
rm -f $argfile
printf "%s" $name | tee -a $argfile
for arg in "$@"; do
printf " \"%s\"" "$arg" | tee -a $argfile
done
printf "\n" | tee -a $argfile
`
)
// EnvironmentPatcher is an interface that requires just one method:
// PatchEnvironment.
type EnvironmentPatcher interface {
PatchEnvironment(name, value string)
}
// 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) {
dir := c.MkDir()
patcher.PatchEnvironment("PATH", joinPathLists(dir, os.Getenv("PATH")))
filename := filepath.Join(dir, execName)
err := ioutil.WriteFile(filename, []byte(script), 0755)
c.Assert(err, gc.IsNil)
}
type CleanupPatcher interface {
PatchEnvironment(name, value string)
AddCleanup(cleanup CleanupFunc)
}
// PatchExecutableAsEchoArgs creates an executable called 'execName' in a new
// 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) {
PatchExecutable(c, patcher, execName, EchoQuotedArgs)
patcher.AddCleanup(func(*gc.C) {
os.Remove(execName + ".out")
})
}
// 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) {
content, err := ioutil.ReadFile(execName + ".out")
c.Assert(err, gc.IsNil)
expected := execName
for _, arg := range args {
expected = fmt.Sprintf("%s %q", expected, arg)
}
expected += "\n"
c.Assert(string(content), gc.Equals, expected)
}