1// Copyright 2018 The Prometheus Authors 2// Licensed under the Apache License, Version 2.0 (the "License"); 3// you may not use this file except in compliance with the License. 4// You may obtain a copy of the License at 5// 6// http://www.apache.org/licenses/LICENSE-2.0 7// 8// Unless required by applicable law or agreed to in writing, software 9// distributed under the License is distributed on an "AS IS" BASIS, 10// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11// See the License for the specific language governing permissions and 12// limitations under the License. 13 14package procfs 15 16import ( 17 "reflect" 18 "sort" 19 "testing" 20) 21 22func TestSelf(t *testing.T) { 23 fs := getProcFixtures(t) 24 25 p1, err := fs.Proc(26231) 26 if err != nil { 27 t.Fatal(err) 28 } 29 p2, err := fs.Self() 30 if err != nil { 31 t.Fatal(err) 32 } 33 34 if !reflect.DeepEqual(p1, p2) { 35 t.Errorf("want process %v, have %v", p1, p2) 36 } 37} 38 39func TestAllProcs(t *testing.T) { 40 procs, err := getProcFixtures(t).AllProcs() 41 if err != nil { 42 t.Fatal(err) 43 } 44 sort.Sort(procs) 45 for i, p := range []*Proc{{PID: 584}, {PID: 26231}} { 46 if want, have := p.PID, procs[i].PID; want != have { 47 t.Errorf("want processes %d, have %d", want, have) 48 } 49 } 50} 51 52func TestCmdLine(t *testing.T) { 53 for _, tt := range []struct { 54 process int 55 want []string 56 }{ 57 {process: 26231, want: []string{"vim", "test.go", "+10"}}, 58 {process: 26232, want: []string{}}, 59 {process: 26233, want: []string{"com.github.uiautomator"}}, 60 } { 61 p1, err := getProcFixtures(t).Proc(tt.process) 62 if err != nil { 63 t.Fatal(err) 64 } 65 c1, err := p1.CmdLine() 66 if err != nil { 67 t.Fatal(err) 68 } 69 if !reflect.DeepEqual(tt.want, c1) { 70 t.Errorf("want cmdline %v, have %v", tt.want, c1) 71 } 72 } 73} 74 75func TestWchan(t *testing.T) { 76 for _, tt := range []struct { 77 process int 78 want string 79 }{ 80 {process: 26231, want: "poll_schedule_timeout"}, 81 {process: 26232, want: ""}, 82 } { 83 p1, err := getProcFixtures(t).Proc(tt.process) 84 if err != nil { 85 t.Fatal(err) 86 } 87 c1, err := p1.Wchan() 88 if err != nil { 89 t.Fatal(err) 90 } 91 if !reflect.DeepEqual(tt.want, c1) { 92 t.Errorf("want wchan %v, have %v", tt.want, c1) 93 } 94 } 95} 96 97func TestComm(t *testing.T) { 98 for _, tt := range []struct { 99 process int 100 want string 101 }{ 102 {process: 26231, want: "vim"}, 103 {process: 26232, want: "ata_sff"}, 104 } { 105 p1, err := getProcFixtures(t).Proc(tt.process) 106 if err != nil { 107 t.Fatal(err) 108 } 109 c1, err := p1.Comm() 110 if err != nil { 111 t.Fatal(err) 112 } 113 if !reflect.DeepEqual(tt.want, c1) { 114 t.Errorf("want comm %v, have %v", tt.want, c1) 115 } 116 } 117} 118 119func TestExecutable(t *testing.T) { 120 for _, tt := range []struct { 121 process int 122 want string 123 }{ 124 {process: 26231, want: "/usr/bin/vim"}, 125 {process: 26232, want: ""}, 126 } { 127 p, err := getProcFixtures(t).Proc(tt.process) 128 if err != nil { 129 t.Fatal(err) 130 } 131 exe, err := p.Executable() 132 if err != nil { 133 t.Fatal(err) 134 } 135 if !reflect.DeepEqual(tt.want, exe) { 136 t.Errorf("want absolute path to exe %v, have %v", tt.want, exe) 137 } 138 } 139} 140 141func TestCwd(t *testing.T) { 142 for _, tt := range []struct { 143 process int 144 want string 145 brokenLink bool 146 }{ 147 {process: 26231, want: "/usr/bin"}, 148 {process: 26232, want: "/does/not/exist", brokenLink: true}, 149 {process: 26233, want: ""}, 150 } { 151 p, err := getProcFixtures(t).Proc(tt.process) 152 if err != nil { 153 t.Fatal(err) 154 } 155 wd, err := p.Cwd() 156 if err != nil { 157 t.Fatal(err) 158 } 159 if !reflect.DeepEqual(tt.want, wd) { 160 if wd == "" && tt.brokenLink { 161 // Allow the result to be empty when can't os.Readlink broken links 162 continue 163 } 164 t.Errorf("want absolute path to cwd %v, have %v", tt.want, wd) 165 } 166 } 167} 168 169func TestRoot(t *testing.T) { 170 for _, tt := range []struct { 171 process int 172 want string 173 brokenLink bool 174 }{ 175 {process: 26231, want: "/"}, 176 {process: 26232, want: "/does/not/exist", brokenLink: true}, 177 {process: 26233, want: ""}, 178 } { 179 p, err := getProcFixtures(t).Proc(tt.process) 180 if err != nil { 181 t.Fatal(err) 182 } 183 rdir, err := p.RootDir() 184 if err != nil { 185 t.Fatal(err) 186 } 187 if !reflect.DeepEqual(tt.want, rdir) { 188 if rdir == "" && tt.brokenLink { 189 // Allow the result to be empty when can't os.Readlink broken links 190 continue 191 } 192 t.Errorf("want absolute path to rootdir %v, have %v", tt.want, rdir) 193 } 194 } 195} 196 197func TestFileDescriptors(t *testing.T) { 198 p1, err := getProcFixtures(t).Proc(26231) 199 if err != nil { 200 t.Fatal(err) 201 } 202 fds, err := p1.FileDescriptors() 203 if err != nil { 204 t.Fatal(err) 205 } 206 sort.Sort(byUintptr(fds)) 207 if want := []uintptr{0, 1, 2, 3, 10}; !reflect.DeepEqual(want, fds) { 208 t.Errorf("want fds %v, have %v", want, fds) 209 } 210} 211 212func TestFileDescriptorTargets(t *testing.T) { 213 p1, err := getProcFixtures(t).Proc(26231) 214 if err != nil { 215 t.Fatal(err) 216 } 217 fds, err := p1.FileDescriptorTargets() 218 if err != nil { 219 t.Fatal(err) 220 } 221 sort.Strings(fds) 222 var want = []string{ 223 "../../symlinktargets/abc", 224 "../../symlinktargets/def", 225 "../../symlinktargets/ghi", 226 "../../symlinktargets/uvw", 227 "../../symlinktargets/xyz", 228 } 229 if !reflect.DeepEqual(want, fds) { 230 t.Errorf("want fds %v, have %v", want, fds) 231 } 232} 233 234func TestFileDescriptorsLen(t *testing.T) { 235 p1, err := getProcFixtures(t).Proc(26231) 236 if err != nil { 237 t.Fatal(err) 238 } 239 l, err := p1.FileDescriptorsLen() 240 if err != nil { 241 t.Fatal(err) 242 } 243 if want, have := 5, l; want != have { 244 t.Errorf("want fds %d, have %d", want, have) 245 } 246} 247 248func TestFileDescriptorsInfo(t *testing.T) { 249 p1, err := getProcFixtures(t).Proc(26231) 250 if err != nil { 251 t.Fatal(err) 252 } 253 fdinfos, err := p1.FileDescriptorsInfo() 254 if err != nil { 255 t.Fatal(err) 256 } 257 sort.Sort(fdinfos) 258 var want = ProcFDInfos{ 259 ProcFDInfo{FD: "0", Pos: "0", Flags: "02004000", MntID: "13", InotifyInfos: []InotifyInfo{ 260 InotifyInfo{WD: "3", Ino: "1", Sdev: "34", Mask: "fce"}, 261 InotifyInfo{WD: "2", Ino: "1300016", Sdev: "fd00002", Mask: "fce"}, 262 InotifyInfo{WD: "1", Ino: "2e0001", Sdev: "fd00000", Mask: "fce"}, 263 }}, 264 ProcFDInfo{FD: "1", Pos: "0", Flags: "02004002", MntID: "13", InotifyInfos: nil}, 265 ProcFDInfo{FD: "10", Pos: "0", Flags: "02004002", MntID: "9", InotifyInfos: nil}, 266 ProcFDInfo{FD: "2", Pos: "0", Flags: "02004002", MntID: "9", InotifyInfos: nil}, 267 ProcFDInfo{FD: "3", Pos: "0", Flags: "02004002", MntID: "9", InotifyInfos: nil}, 268 } 269 if !reflect.DeepEqual(want, fdinfos) { 270 t.Errorf("want fdinfos %+v, have %+v", want, fdinfos) 271 } 272} 273 274type byUintptr []uintptr 275 276func (a byUintptr) Len() int { return len(a) } 277func (a byUintptr) Swap(i, j int) { a[i], a[j] = a[j], a[i] } 278func (a byUintptr) Less(i, j int) bool { return a[i] < a[j] } 279