提交 fc513b6f 编写于 作者: S Shirou WAKAYAMA

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.
上级 026d4a35
......@@ -9,12 +9,60 @@ package common
import (
"bufio"
"errors"
"io/ioutil"
"net/url"
"os"
"os/exec"
"path"
"reflect"
"runtime"
"strconv"
"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")
// ReadLines reads contents from a file and splits them by new lines.
......
PID
245
247
248
249
254
262
264
265
267
......@@ -5,9 +5,16 @@ import (
"runtime"
"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 {
Pid int32 `json:"pid"`
name string
......
......@@ -4,15 +4,14 @@ package process
import (
"bytes"
"os/exec"
"strconv"
"strings"
"syscall"
"unsafe"
common "github.com/shirou/gopsutil/common"
cpu "github.com/shirou/gopsutil/cpu"
net "github.com/shirou/gopsutil/net"
"github.com/shirou/gopsutil/common"
"github.com/shirou/gopsutil/cpu"
"github.com/shirou/gopsutil/net"
)
// copied from sys/sysctl.h
......@@ -391,7 +390,7 @@ func callPs(arg string, pid int32, threadOption bool) ([][]string, error) {
} else {
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 {
return [][]string{}, err
}
......
package process
import (
"fmt"
"os"
"runtime"
"strings"
"sync"
"testing"
"time"
"github.com/shirou/gopsutil/common"
)
var mu sync.Mutex
func testGetProcess() Process {
checkPid := os.Getpid() // process.test
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) {
checkPid := os.Getpid()
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册