proces[darwin]: change exec.Command to interface to enable mocking.

Add common.invoker interface to mock exec.Command. common.FakeInvoker returns
expected file if exists instead of invoke exec.Command.
Currenly, mocking is enabled only process.Pids(). I will expand to other funcs incrementally.
pull/79/head
Shirou WAKAYAMA 10 years ago
parent 026d4a3519
commit fc513b6f9a

@ -9,12 +9,60 @@ package common
import ( import (
"bufio" "bufio"
"errors" "errors"
"io/ioutil"
"net/url"
"os" "os"
"os/exec"
"path"
"reflect" "reflect"
"runtime"
"strconv" "strconv"
"strings" "strings"
) )
type Invoker interface {
Command(string, ...string) ([]byte, error)
}
type Invoke struct{}
func (i Invoke) Command(name string, arg ...string) ([]byte, error) {
return exec.Command(name, arg...).Output()
}
type FakeInvoke struct {
CommandExpectedDir string // CommandExpectedDir specifies dir which includes expected outputs.
Suffix string // Suffix species expected file name suffix such as "fail"
Error error // If Error specfied, return the error.
}
// Command in FakeInvoke returns from expected file if exists.
func (i FakeInvoke) Command(name string, arg ...string) ([]byte, error) {
if i.Error != nil {
return []byte{}, i.Error
}
arch := runtime.GOOS
fname := strings.Join(append([]string{name}, arg...), "")
fname = url.QueryEscape(fname)
var dir string
if i.CommandExpectedDir == "" {
dir = "expected"
} else {
dir = i.CommandExpectedDir
}
fpath := path.Join(dir, arch, fname)
if i.Suffix != "" {
fpath += "_" + i.Suffix
}
if PathExists(fpath) {
return ioutil.ReadFile(fpath)
} else {
return exec.Command(name, arg...).Output()
}
}
var NotImplementedError = errors.New("not implemented yet") var NotImplementedError = errors.New("not implemented yet")
// ReadLines reads contents from a file and splits them by new lines. // ReadLines reads contents from a file and splits them by new lines.

@ -0,0 +1,10 @@
PID
245
247
248
249
254
262
264
265
267

@ -5,9 +5,16 @@ import (
"runtime" "runtime"
"time" "time"
cpu "github.com/shirou/gopsutil/cpu" "github.com/shirou/gopsutil/common"
"github.com/shirou/gopsutil/cpu"
) )
var invoke common.Invoker
func init() {
invoke = common.Invoke{}
}
type Process struct { type Process struct {
Pid int32 `json:"pid"` Pid int32 `json:"pid"`
name string name string

@ -4,15 +4,14 @@ package process
import ( import (
"bytes" "bytes"
"os/exec"
"strconv" "strconv"
"strings" "strings"
"syscall" "syscall"
"unsafe" "unsafe"
common "github.com/shirou/gopsutil/common" "github.com/shirou/gopsutil/common"
cpu "github.com/shirou/gopsutil/cpu" "github.com/shirou/gopsutil/cpu"
net "github.com/shirou/gopsutil/net" "github.com/shirou/gopsutil/net"
) )
// copied from sys/sysctl.h // copied from sys/sysctl.h
@ -391,7 +390,7 @@ func callPs(arg string, pid int32, threadOption bool) ([][]string, error) {
} else { } else {
cmd = []string{"-x", "-o", arg, "-p", strconv.Itoa(int(pid))} cmd = []string{"-x", "-o", arg, "-p", strconv.Itoa(int(pid))}
} }
out, err := exec.Command("/bin/ps", cmd...).Output() out, err := invoke.Command("/bin/ps", cmd...)
if err != nil { if err != nil {
return [][]string{}, err return [][]string{}, err
} }

@ -1,13 +1,19 @@
package process package process
import ( import (
"fmt"
"os" "os"
"runtime" "runtime"
"strings" "strings"
"sync"
"testing" "testing"
"time" "time"
"github.com/shirou/gopsutil/common"
) )
var mu sync.Mutex
func testGetProcess() Process { func testGetProcess() Process {
checkPid := os.Getpid() // process.test checkPid := os.Getpid() // process.test
ret, _ := NewProcess(int32(checkPid)) ret, _ := NewProcess(int32(checkPid))
@ -24,6 +30,21 @@ func Test_Pids(t *testing.T) {
} }
} }
func Test_Pids_Fail(t *testing.T) {
mu.Lock()
defer mu.Unlock()
invoke = common.FakeInvoke{Suffix: "fail", Error: fmt.Errorf("hoge")}
ret, err := Pids()
invoke = common.Invoke{}
if err != nil {
t.Errorf("error %v", err)
}
if len(ret) != 9 {
t.Errorf("wrong getted pid nums: %v/%d", ret, len(ret))
}
}
func Test_Pid_exists(t *testing.T) { func Test_Pid_exists(t *testing.T) {
checkPid := os.Getpid() checkPid := os.Getpid()

Loading…
Cancel
Save