1
1
package goprocess
2
2
3
3
import (
4
+ "io/ioutil"
5
+ "os"
6
+ "path/filepath"
4
7
"reflect"
8
+ "runtime"
5
9
"sort"
10
+ "strconv"
6
11
"testing"
7
12
8
- "github.com/keybase/go-ps "
13
+ "github.com/shirou/gopsutil/v3/process "
9
14
)
10
15
11
16
func BenchmarkFindAll(b *testing.B) {
@@ -16,12 +21,21 @@ func BenchmarkFindAll(b *testing.B) {
16
21
17
22
// TestFindAll tests findAll implementation function.
18
23
func TestFindAll(t *testing.T) {
24
+ testProcess, err := process.NewProcess(int32(os.Getpid()))
25
+ if err != nil {
26
+ t.Errorf("failed to get current process: %v", err)
27
+ }
28
+ testPpid, _ := testProcess.Ppid()
29
+ testExec, _ := testProcess.Name()
30
+ wantProcess := P{PID: int(testProcess.Pid), PPID: int(testPpid), Exec: testExec}
31
+
19
32
for _, tc := range []struct {
20
33
name string
21
34
concurrencyLimit int
22
- input []ps .Process
35
+ input []*process .Process
23
36
goPIDs []int
24
37
want []P
38
+ mock bool
25
39
}{{
26
40
name: "no processes",
27
41
concurrencyLimit: 10,
@@ -30,28 +44,57 @@ func TestFindAll(t *testing.T) {
30
44
}, {
31
45
name: "non-Go process",
32
46
concurrencyLimit: 10,
33
- input: fakeProcessesWithPIDs(1) ,
47
+ input: []*process.Process{testProcess} ,
34
48
want: nil,
35
49
}, {
36
50
name: "Go process",
37
51
concurrencyLimit: 10,
38
- input: fakeProcessesWithPIDs(1) ,
39
- goPIDs: []int{1 },
40
- want: []P{{PID: 1} },
52
+ input: []*process.Process{testProcess} ,
53
+ goPIDs: []int{int(testProcess.Pid) },
54
+ want: []P{wantProcess },
41
55
}, {
42
56
name: "filters Go processes",
43
57
concurrencyLimit: 10,
44
58
input: fakeProcessesWithPIDs(1, 2, 3, 4, 5, 6, 7),
45
59
goPIDs: []int{1, 3, 5, 7},
46
60
want: []P{{PID: 1}, {PID: 3}, {PID: 5}, {PID: 7}},
61
+ mock: true,
47
62
}, {
48
63
name: "Go processes above max concurrency (issue #123)",
49
64
concurrencyLimit: 2,
50
65
input: fakeProcessesWithPIDs(1, 2, 3, 4, 5, 6, 7),
51
66
goPIDs: []int{1, 3, 5, 7},
52
67
want: []P{{PID: 1}, {PID: 3}, {PID: 5}, {PID: 7}},
68
+ mock: true,
53
69
}} {
54
70
t.Run(tc.name, func(t *testing.T) {
71
+ if tc.mock {
72
+ if runtime.GOOS != "linux" {
73
+ t.Skip()
74
+ }
75
+ tempDir, err := ioutil.TempDir("", "")
76
+ if err != nil {
77
+ t.Errorf("failed to create temp dir: %v", err)
78
+ }
79
+ defer os.RemoveAll(tempDir)
80
+ for _, p := range tc.input {
81
+ os.Mkdir(filepath.Join(tempDir, strconv.Itoa(int(p.Pid))), 0o755)
82
+ ioutil.WriteFile(filepath.Join(tempDir, strconv.Itoa(int(p.Pid)), "stat"), []byte(
83
+ `1440024 () R 0 1440024 0 34821 1440024 4194304 134 0 0 0 0 0 0 0 20 0 1 0 95120609 6746112 274 18446744073709551615 94467689938944 94467690036601 140724224197808 0 0 0 0 0 0 0 0 0 17 11 0 0 0 0 0 94467690068048 94467690071296 94467715629056 140724224199226 140724224199259 140724224199259 140724224204780 0`,
84
+ ), 0o644)
85
+ ioutil.WriteFile(filepath.Join(tempDir, strconv.Itoa(int(p.Pid)), "status"), []byte(
86
+ `Name:
87
+ Umask: 0022
88
+ State: R (running)
89
+ Tgid: 1440366
90
+ Ngid: 0
91
+ Pid: 1440366
92
+ PPid: 0
93
+ `,
94
+ ), 0o644)
95
+ }
96
+ os.Setenv("HOST_PROC", tempDir)
97
+ }
55
98
actual := findAll(tc.input, fakeIsGo(tc.goPIDs), tc.concurrencyLimit)
56
99
sort.Slice(actual, func(i, j int) bool { return actual[i].PID < actual[j].PID })
57
100
if !reflect.DeepEqual(actual, tc.want) {
@@ -63,9 +106,9 @@ func TestFindAll(t *testing.T) {
63
106
}
64
107
65
108
func fakeIsGo(goPIDs []int) isGoFunc {
66
- return func(pr ps .Process) (path, version string, agent, ok bool, err error) {
109
+ return func(pr *process .Process) (path, version string, agent, ok bool, err error) {
67
110
for _, p := range goPIDs {
68
- if p == pr.Pid( ) {
111
+ if p == int( pr.Pid) {
69
112
ok = true
70
113
return
71
114
}
@@ -74,19 +117,10 @@ func fakeIsGo(goPIDs []int) isGoFunc {
74
117
}
75
118
}
76
119
77
- func fakeProcessesWithPIDs(pids ...int) []ps .Process {
78
- p := make([]ps .Process, 0, len(pids))
120
+ func fakeProcessesWithPIDs(pids ...int) []*process .Process {
121
+ p := make([]*process .Process, 0, len(pids))
79
122
for _, pid := range pids {
80
- p = append(p, fakeProcess{pid: pid})
123
+ p = append(p, &process.Process{Pid: int32( pid) })
81
124
}
82
125
return p
83
126
}
84
-
85
- type fakeProcess struct {
86
- ps.Process
87
- pid int
88
- }
89
-
90
- func (p fakeProcess) Pid() int { return p.pid }
91
- func (p fakeProcess) PPid() int { return 0 }
92
- func (p fakeProcess) Executable() string { return "" }
0 commit comments