1
2
3 package process
4
5 import (
6 "context"
7 "fmt"
8 "io/ioutil"
9 "os"
10 "strconv"
11 "strings"
12 "testing"
13
14 "github.com/shirou/gopsutil/internal/common"
15 "github.com/stretchr/testify/assert"
16 )
17
18 func Test_Process_splitProcStat(t *testing.T) {
19 expectedFieldsNum := 53
20 statLineContent := make([]string, expectedFieldsNum-1)
21 for i := 0; i < expectedFieldsNum-1; i++ {
22 statLineContent[i] = strconv.Itoa(i + 1)
23 }
24
25 cases := []string{
26 "ok",
27 "ok)",
28 "(ok",
29 "ok )",
30 "ok )(",
31 "ok )()",
32 "() ok )()",
33 "() ok (()",
34 " ) ok )",
35 "(ok) (ok)",
36 }
37
38 consideredFields := []int{4, 7, 10, 11, 12, 13, 14, 15, 18, 22, 42}
39
40 commandNameIndex := 2
41 for _, expectedName := range cases {
42 statLineContent[commandNameIndex-1] = "(" + expectedName + ")"
43 statLine := strings.Join(statLineContent, " ")
44 t.Run(fmt.Sprintf("name: %s", expectedName), func(t *testing.T) {
45 parsedStatLine := splitProcStat([]byte(statLine))
46 assert.Equal(t, expectedName, parsedStatLine[commandNameIndex])
47 for _, idx := range consideredFields {
48 expected := strconv.Itoa(idx)
49 parsed := parsedStatLine[idx]
50 assert.Equal(
51 t, expected, parsed,
52 "field %d (index from 1 as in man proc) must be %q but %q is received",
53 idx, expected, parsed,
54 )
55 }
56 })
57 }
58 }
59
60 func Test_Process_splitProcStat_fromFile(t *testing.T) {
61 pids, err := ioutil.ReadDir("testdata/linux/")
62 if err != nil {
63 t.Error(err)
64 }
65 f := common.MockEnv("HOST_PROC", "testdata/linux")
66 defer f()
67 for _, pid := range pids {
68 pid, err := strconv.ParseInt(pid.Name(), 0, 32)
69 if err != nil {
70 continue
71 }
72 statFile := fmt.Sprintf("testdata/linux/%d/stat", pid)
73 if _, err := os.Stat(statFile); err != nil {
74 continue
75 }
76 contents, err := ioutil.ReadFile(statFile)
77 assert.NoError(t, err)
78
79 pidStr := strconv.Itoa(int(pid))
80
81 ppid := "68044"
82
83 fields := splitProcStat(contents)
84 assert.Equal(t, fields[1], pidStr)
85 assert.Equal(t, fields[2], "test(cmd).sh")
86 assert.Equal(t, fields[3], "S")
87 assert.Equal(t, fields[4], ppid)
88 assert.Equal(t, fields[5], pidStr)
89 assert.Equal(t, fields[6], ppid)
90 assert.Equal(t, fields[8], pidStr)
91 assert.Equal(t, fields[18], "20")
92 assert.Equal(t, fields[20], "1")
93 assert.Equal(t, fields[52], "0")
94 }
95 }
96
97 func Test_fillFromStatusWithContext(t *testing.T) {
98 pids, err := ioutil.ReadDir("testdata/linux/")
99 if err != nil {
100 t.Error(err)
101 }
102 f := common.MockEnv("HOST_PROC", "testdata/linux")
103 defer f()
104 for _, pid := range pids {
105 pid, err := strconv.ParseInt(pid.Name(), 0, 32)
106 if err != nil {
107 continue
108 }
109 if _, err := os.Stat(fmt.Sprintf("testdata/linux/%d/status", pid)); err != nil {
110 continue
111 }
112 p, _ := NewProcess(int32(pid))
113 if err := p.fillFromStatusWithContext(context.Background()); err != nil {
114 t.Error(err)
115 }
116 }
117 }
118
119 func Test_fillFromTIDStatWithContext_lx_brandz(t *testing.T) {
120 pids, err := ioutil.ReadDir("testdata/lx_brandz/")
121 if err != nil {
122 t.Error(err)
123 }
124 f := common.MockEnv("HOST_PROC", "testdata/lx_brandz")
125 defer f()
126 for _, pid := range pids {
127 pid, err := strconv.ParseInt(pid.Name(), 0, 32)
128 if err != nil {
129 continue
130 }
131 if _, err := os.Stat(fmt.Sprintf("testdata/lx_brandz/%d/stat", pid)); err != nil {
132 continue
133 }
134 p, _ := NewProcess(int32(pid))
135 _, _, cpuTimes, _, _, _, _, err := p.fillFromTIDStatWithContext(context.Background(), -1)
136 if err != nil {
137 t.Error(err)
138 }
139 assert.Equal(t, float64(0), cpuTimes.Iowait)
140 }
141 }
142
View as plain text