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 := FS("fixtures") 24 25 p1, err := fs.NewProc(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 := FS("fixtures").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 := FS("fixtures").NewProc(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 TestComm(t *testing.T) { 76 for _, tt := range []struct { 77 process int 78 want string 79 }{ 80 {process: 26231, want: "vim"}, 81 {process: 26232, want: "ata_sff"}, 82 } { 83 p1, err := FS("fixtures").NewProc(tt.process) 84 if err != nil { 85 t.Fatal(err) 86 } 87 c1, err := p1.Comm() 88 if err != nil { 89 t.Fatal(err) 90 } 91 if !reflect.DeepEqual(tt.want, c1) { 92 t.Errorf("want comm %v, have %v", tt.want, c1) 93 } 94 } 95} 96 97func TestExecutable(t *testing.T) { 98 for _, tt := range []struct { 99 process int 100 want string 101 }{ 102 {process: 26231, want: "/usr/bin/vim"}, 103 {process: 26232, want: ""}, 104 } { 105 p, err := FS("fixtures").NewProc(tt.process) 106 if err != nil { 107 t.Fatal(err) 108 } 109 exe, err := p.Executable() 110 if err != nil { 111 t.Fatal(err) 112 } 113 if !reflect.DeepEqual(tt.want, exe) { 114 t.Errorf("want absolute path to exe %v, have %v", tt.want, exe) 115 } 116 } 117} 118 119func TestCwd(t *testing.T) { 120 for _, tt := range []struct { 121 process int 122 want string 123 brokenLink bool 124 }{ 125 {process: 26231, want: "/usr/bin"}, 126 {process: 26232, want: "/does/not/exist", brokenLink: true}, 127 {process: 26233, want: ""}, 128 } { 129 p, err := FS("fixtures").NewProc(tt.process) 130 if err != nil { 131 t.Fatal(err) 132 } 133 wd, err := p.Cwd() 134 if err != nil { 135 t.Fatal(err) 136 } 137 if !reflect.DeepEqual(tt.want, wd) { 138 if wd == "" && tt.brokenLink { 139 // Allow the result to be empty when can't os.Readlink broken links 140 continue 141 } 142 t.Errorf("want absolute path to cwd %v, have %v", tt.want, wd) 143 } 144 } 145} 146 147func TestRoot(t *testing.T) { 148 for _, tt := range []struct { 149 process int 150 want string 151 brokenLink bool 152 }{ 153 {process: 26231, want: "/"}, 154 {process: 26232, want: "/does/not/exist", brokenLink: true}, 155 {process: 26233, want: ""}, 156 } { 157 p, err := FS("fixtures").NewProc(tt.process) 158 if err != nil { 159 t.Fatal(err) 160 } 161 rdir, err := p.RootDir() 162 if err != nil { 163 t.Fatal(err) 164 } 165 if !reflect.DeepEqual(tt.want, rdir) { 166 if rdir == "" && tt.brokenLink { 167 // Allow the result to be empty when can't os.Readlink broken links 168 continue 169 } 170 t.Errorf("want absolute path to rootdir %v, have %v", tt.want, rdir) 171 } 172 } 173} 174 175func TestFileDescriptors(t *testing.T) { 176 p1, err := FS("fixtures").NewProc(26231) 177 if err != nil { 178 t.Fatal(err) 179 } 180 fds, err := p1.FileDescriptors() 181 if err != nil { 182 t.Fatal(err) 183 } 184 sort.Sort(byUintptr(fds)) 185 if want := []uintptr{0, 1, 2, 3, 10}; !reflect.DeepEqual(want, fds) { 186 t.Errorf("want fds %v, have %v", want, fds) 187 } 188} 189 190func TestFileDescriptorTargets(t *testing.T) { 191 p1, err := FS("fixtures").NewProc(26231) 192 if err != nil { 193 t.Fatal(err) 194 } 195 fds, err := p1.FileDescriptorTargets() 196 if err != nil { 197 t.Fatal(err) 198 } 199 sort.Strings(fds) 200 var want = []string{ 201 "../../symlinktargets/abc", 202 "../../symlinktargets/def", 203 "../../symlinktargets/ghi", 204 "../../symlinktargets/uvw", 205 "../../symlinktargets/xyz", 206 } 207 if !reflect.DeepEqual(want, fds) { 208 t.Errorf("want fds %v, have %v", want, fds) 209 } 210} 211 212func TestFileDescriptorsLen(t *testing.T) { 213 p1, err := FS("fixtures").NewProc(26231) 214 if err != nil { 215 t.Fatal(err) 216 } 217 l, err := p1.FileDescriptorsLen() 218 if err != nil { 219 t.Fatal(err) 220 } 221 if want, have := 5, l; want != have { 222 t.Errorf("want fds %d, have %d", want, have) 223 } 224} 225 226type byUintptr []uintptr 227 228func (a byUintptr) Len() int { return len(a) } 229func (a byUintptr) Swap(i, j int) { a[i], a[j] = a[j], a[i] } 230func (a byUintptr) Less(i, j int) bool { return a[i] < a[j] } 231