github.com/lovishpuri/go-40569/src@v0.0.0-20230519171745-f8623e7c56cf/os/user/lookup_unix_test.go (about) 1 // Copyright 2016 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 //go:build unix && !android && !cgo && !darwin 6 7 package user 8 9 import ( 10 "reflect" 11 "strings" 12 "testing" 13 ) 14 15 var groupTests = []struct { 16 in string 17 name string 18 gid string 19 }{ 20 {testGroupFile, "nobody", "-2"}, 21 {testGroupFile, "kmem", "2"}, 22 {testGroupFile, "notinthefile", ""}, 23 {testGroupFile, "comment", ""}, 24 {testGroupFile, "plussign", ""}, 25 {testGroupFile, "+plussign", ""}, 26 {testGroupFile, "-minussign", ""}, 27 {testGroupFile, "minussign", ""}, 28 {testGroupFile, "emptyid", ""}, 29 {testGroupFile, "invalidgid", ""}, 30 {testGroupFile, "indented", "7"}, 31 {testGroupFile, "# comment", ""}, 32 {testGroupFile, "largegroup", "1000"}, 33 {testGroupFile, "manymembers", "777"}, 34 {"", "emptyfile", ""}, 35 } 36 37 func TestFindGroupName(t *testing.T) { 38 for _, tt := range groupTests { 39 got, err := findGroupName(tt.name, strings.NewReader(tt.in)) 40 if tt.gid == "" { 41 if err == nil { 42 t.Errorf("findGroupName(%s): got nil error, expected err", tt.name) 43 continue 44 } 45 switch terr := err.(type) { 46 case UnknownGroupError: 47 if terr.Error() != "group: unknown group "+tt.name { 48 t.Errorf("findGroupName(%s): got %v, want %v", tt.name, terr, tt.name) 49 } 50 default: 51 t.Errorf("findGroupName(%s): got unexpected error %v", tt.name, terr) 52 } 53 } else { 54 if err != nil { 55 t.Fatalf("findGroupName(%s): got unexpected error %v", tt.name, err) 56 } 57 if got.Gid != tt.gid { 58 t.Errorf("findGroupName(%s): got gid %v, want %s", tt.name, got.Gid, tt.gid) 59 } 60 if got.Name != tt.name { 61 t.Errorf("findGroupName(%s): got name %s, want %s", tt.name, got.Name, tt.name) 62 } 63 } 64 } 65 } 66 67 var groupIdTests = []struct { 68 in string 69 gid string 70 name string 71 }{ 72 {testGroupFile, "-2", "nobody"}, 73 {testGroupFile, "2", "kmem"}, 74 {testGroupFile, "notinthefile", ""}, 75 {testGroupFile, "comment", ""}, 76 {testGroupFile, "7", "indented"}, 77 {testGroupFile, "4", ""}, 78 {testGroupFile, "20", ""}, // row starts with a plus 79 {testGroupFile, "21", ""}, // row starts with a minus 80 {"", "emptyfile", ""}, 81 } 82 83 func TestFindGroupId(t *testing.T) { 84 for _, tt := range groupIdTests { 85 got, err := findGroupId(tt.gid, strings.NewReader(tt.in)) 86 if tt.name == "" { 87 if err == nil { 88 t.Errorf("findGroupId(%s): got nil error, expected err", tt.gid) 89 continue 90 } 91 switch terr := err.(type) { 92 case UnknownGroupIdError: 93 if terr.Error() != "group: unknown groupid "+tt.gid { 94 t.Errorf("findGroupId(%s): got %v, want %v", tt.name, terr, tt.name) 95 } 96 default: 97 t.Errorf("findGroupId(%s): got unexpected error %v", tt.name, terr) 98 } 99 } else { 100 if err != nil { 101 t.Fatalf("findGroupId(%s): got unexpected error %v", tt.name, err) 102 } 103 if got.Gid != tt.gid { 104 t.Errorf("findGroupId(%s): got gid %v, want %s", tt.name, got.Gid, tt.gid) 105 } 106 if got.Name != tt.name { 107 t.Errorf("findGroupId(%s): got name %s, want %s", tt.name, got.Name, tt.name) 108 } 109 } 110 } 111 } 112 113 const testUserFile = ` # Example user file 114 root:x:0:0:root:/root:/bin/bash 115 daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin 116 bin:x:2:3:bin:/bin:/usr/sbin/nologin 117 indented:x:3:3:indented:/dev:/usr/sbin/nologin 118 sync:x:4:65534:sync:/bin:/bin/sync 119 negative:x:-5:60:games:/usr/games:/usr/sbin/nologin 120 man:x:6:12:man:/var/cache/man:/usr/sbin/nologin 121 allfields:x:6:12:mansplit,man2,man3,man4:/home/allfields:/usr/sbin/nologin 122 +plussign:x:8:10:man:/var/cache/man:/usr/sbin/nologin 123 -minussign:x:9:10:man:/var/cache/man:/usr/sbin/nologin 124 125 malformed:x:27:12 # more:colons:after:comment 126 127 struid:x:notanumber:12 # more:colons:after:comment 128 129 # commented:x:28:12:commented:/var/cache/man:/usr/sbin/nologin 130 # commentindented:x:29:12:commentindented:/var/cache/man:/usr/sbin/nologin 131 132 struid2:x:30:badgid:struid2name:/home/struid:/usr/sbin/nologin 133 ` 134 135 var userIdTests = []struct { 136 in string 137 uid string 138 name string 139 }{ 140 {testUserFile, "-5", "negative"}, 141 {testUserFile, "2", "bin"}, 142 {testUserFile, "100", ""}, // not in the file 143 {testUserFile, "8", ""}, // plus sign, glibc doesn't find it 144 {testUserFile, "9", ""}, // minus sign, glibc doesn't find it 145 {testUserFile, "27", ""}, // malformed 146 {testUserFile, "28", ""}, // commented out 147 {testUserFile, "29", ""}, // commented out, indented 148 {testUserFile, "3", "indented"}, 149 {testUserFile, "30", ""}, // the Gid is not valid, shouldn't match 150 {"", "1", ""}, 151 } 152 153 func TestInvalidUserId(t *testing.T) { 154 _, err := findUserId("notanumber", strings.NewReader("")) 155 if err == nil { 156 t.Fatalf("findUserId('notanumber'): got nil error") 157 } 158 if want := "user: invalid userid notanumber"; err.Error() != want { 159 t.Errorf("findUserId('notanumber'): got %v, want %s", err, want) 160 } 161 } 162 163 func TestLookupUserId(t *testing.T) { 164 for _, tt := range userIdTests { 165 got, err := findUserId(tt.uid, strings.NewReader(tt.in)) 166 if tt.name == "" { 167 if err == nil { 168 t.Errorf("findUserId(%s): got nil error, expected err", tt.uid) 169 continue 170 } 171 switch terr := err.(type) { 172 case UnknownUserIdError: 173 if want := "user: unknown userid " + tt.uid; terr.Error() != want { 174 t.Errorf("findUserId(%s): got %v, want %v", tt.name, terr, want) 175 } 176 default: 177 t.Errorf("findUserId(%s): got unexpected error %v", tt.name, terr) 178 } 179 } else { 180 if err != nil { 181 t.Fatalf("findUserId(%s): got unexpected error %v", tt.name, err) 182 } 183 if got.Uid != tt.uid { 184 t.Errorf("findUserId(%s): got uid %v, want %s", tt.name, got.Uid, tt.uid) 185 } 186 if got.Username != tt.name { 187 t.Errorf("findUserId(%s): got name %s, want %s", tt.name, got.Username, tt.name) 188 } 189 } 190 } 191 } 192 193 func TestLookupUserPopulatesAllFields(t *testing.T) { 194 u, err := findUsername("allfields", strings.NewReader(testUserFile)) 195 if err != nil { 196 t.Fatal(err) 197 } 198 want := &User{ 199 Username: "allfields", 200 Uid: "6", 201 Gid: "12", 202 Name: "mansplit", 203 HomeDir: "/home/allfields", 204 } 205 if !reflect.DeepEqual(u, want) { 206 t.Errorf("findUsername: got %#v, want %#v", u, want) 207 } 208 } 209 210 var userTests = []struct { 211 in string 212 name string 213 uid string 214 }{ 215 {testUserFile, "negative", "-5"}, 216 {testUserFile, "bin", "2"}, 217 {testUserFile, "notinthefile", ""}, 218 {testUserFile, "indented", "3"}, 219 {testUserFile, "plussign", ""}, 220 {testUserFile, "+plussign", ""}, 221 {testUserFile, "minussign", ""}, 222 {testUserFile, "-minussign", ""}, 223 {testUserFile, " indented", ""}, 224 {testUserFile, "commented", ""}, 225 {testUserFile, "commentindented", ""}, 226 {testUserFile, "malformed", ""}, 227 {testUserFile, "# commented", ""}, 228 {"", "emptyfile", ""}, 229 } 230 231 func TestLookupUser(t *testing.T) { 232 for _, tt := range userTests { 233 got, err := findUsername(tt.name, strings.NewReader(tt.in)) 234 if tt.uid == "" { 235 if err == nil { 236 t.Errorf("lookupUser(%s): got nil error, expected err", tt.uid) 237 continue 238 } 239 switch terr := err.(type) { 240 case UnknownUserError: 241 if want := "user: unknown user " + tt.name; terr.Error() != want { 242 t.Errorf("lookupUser(%s): got %v, want %v", tt.name, terr, want) 243 } 244 default: 245 t.Errorf("lookupUser(%s): got unexpected error %v", tt.name, terr) 246 } 247 } else { 248 if err != nil { 249 t.Fatalf("lookupUser(%s): got unexpected error %v", tt.name, err) 250 } 251 if got.Uid != tt.uid { 252 t.Errorf("lookupUser(%s): got uid %v, want %s", tt.name, got.Uid, tt.uid) 253 } 254 if got.Username != tt.name { 255 t.Errorf("lookupUser(%s): got name %s, want %s", tt.name, got.Username, tt.name) 256 } 257 } 258 } 259 }