diff options
Diffstat (limited to 'src/os/user/lookup_unix_test.go')
-rw-r--r-- | src/os/user/lookup_unix_test.go | 259 |
1 files changed, 259 insertions, 0 deletions
diff --git a/src/os/user/lookup_unix_test.go b/src/os/user/lookup_unix_test.go new file mode 100644 index 0000000..399a03f --- /dev/null +++ b/src/os/user/lookup_unix_test.go @@ -0,0 +1,259 @@ +// Copyright 2016 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +//go:build unix && !android && !cgo + +package user + +import ( + "reflect" + "strings" + "testing" +) + +var groupTests = []struct { + in string + name string + gid string +}{ + {testGroupFile, "nobody", "-2"}, + {testGroupFile, "kmem", "2"}, + {testGroupFile, "notinthefile", ""}, + {testGroupFile, "comment", ""}, + {testGroupFile, "plussign", ""}, + {testGroupFile, "+plussign", ""}, + {testGroupFile, "-minussign", ""}, + {testGroupFile, "minussign", ""}, + {testGroupFile, "emptyid", ""}, + {testGroupFile, "invalidgid", ""}, + {testGroupFile, "indented", "7"}, + {testGroupFile, "# comment", ""}, + {testGroupFile, "largegroup", "1000"}, + {testGroupFile, "manymembers", "777"}, + {"", "emptyfile", ""}, +} + +func TestFindGroupName(t *testing.T) { + for _, tt := range groupTests { + got, err := findGroupName(tt.name, strings.NewReader(tt.in)) + if tt.gid == "" { + if err == nil { + t.Errorf("findGroupName(%s): got nil error, expected err", tt.name) + continue + } + switch terr := err.(type) { + case UnknownGroupError: + if terr.Error() != "group: unknown group "+tt.name { + t.Errorf("findGroupName(%s): got %v, want %v", tt.name, terr, tt.name) + } + default: + t.Errorf("findGroupName(%s): got unexpected error %v", tt.name, terr) + } + } else { + if err != nil { + t.Fatalf("findGroupName(%s): got unexpected error %v", tt.name, err) + } + if got.Gid != tt.gid { + t.Errorf("findGroupName(%s): got gid %v, want %s", tt.name, got.Gid, tt.gid) + } + if got.Name != tt.name { + t.Errorf("findGroupName(%s): got name %s, want %s", tt.name, got.Name, tt.name) + } + } + } +} + +var groupIdTests = []struct { + in string + gid string + name string +}{ + {testGroupFile, "-2", "nobody"}, + {testGroupFile, "2", "kmem"}, + {testGroupFile, "notinthefile", ""}, + {testGroupFile, "comment", ""}, + {testGroupFile, "7", "indented"}, + {testGroupFile, "4", ""}, + {testGroupFile, "20", ""}, // row starts with a plus + {testGroupFile, "21", ""}, // row starts with a minus + {"", "emptyfile", ""}, +} + +func TestFindGroupId(t *testing.T) { + for _, tt := range groupIdTests { + got, err := findGroupId(tt.gid, strings.NewReader(tt.in)) + if tt.name == "" { + if err == nil { + t.Errorf("findGroupId(%s): got nil error, expected err", tt.gid) + continue + } + switch terr := err.(type) { + case UnknownGroupIdError: + if terr.Error() != "group: unknown groupid "+tt.gid { + t.Errorf("findGroupId(%s): got %v, want %v", tt.name, terr, tt.name) + } + default: + t.Errorf("findGroupId(%s): got unexpected error %v", tt.name, terr) + } + } else { + if err != nil { + t.Fatalf("findGroupId(%s): got unexpected error %v", tt.name, err) + } + if got.Gid != tt.gid { + t.Errorf("findGroupId(%s): got gid %v, want %s", tt.name, got.Gid, tt.gid) + } + if got.Name != tt.name { + t.Errorf("findGroupId(%s): got name %s, want %s", tt.name, got.Name, tt.name) + } + } + } +} + +const testUserFile = ` # Example user file +root:x:0:0:root:/root:/bin/bash +daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin +bin:x:2:3:bin:/bin:/usr/sbin/nologin + indented:x:3:3:indented:/dev:/usr/sbin/nologin +sync:x:4:65534:sync:/bin:/bin/sync +negative:x:-5:60:games:/usr/games:/usr/sbin/nologin +man:x:6:12:man:/var/cache/man:/usr/sbin/nologin +allfields:x:6:12:mansplit,man2,man3,man4:/home/allfields:/usr/sbin/nologin ++plussign:x:8:10:man:/var/cache/man:/usr/sbin/nologin +-minussign:x:9:10:man:/var/cache/man:/usr/sbin/nologin + +malformed:x:27:12 # more:colons:after:comment + +struid:x:notanumber:12 # more:colons:after:comment + +# commented:x:28:12:commented:/var/cache/man:/usr/sbin/nologin + # commentindented:x:29:12:commentindented:/var/cache/man:/usr/sbin/nologin + +struid2:x:30:badgid:struid2name:/home/struid:/usr/sbin/nologin +` + +var userIdTests = []struct { + in string + uid string + name string +}{ + {testUserFile, "-5", "negative"}, + {testUserFile, "2", "bin"}, + {testUserFile, "100", ""}, // not in the file + {testUserFile, "8", ""}, // plus sign, glibc doesn't find it + {testUserFile, "9", ""}, // minus sign, glibc doesn't find it + {testUserFile, "27", ""}, // malformed + {testUserFile, "28", ""}, // commented out + {testUserFile, "29", ""}, // commented out, indented + {testUserFile, "3", "indented"}, + {testUserFile, "30", ""}, // the Gid is not valid, shouldn't match + {"", "1", ""}, +} + +func TestInvalidUserId(t *testing.T) { + _, err := findUserId("notanumber", strings.NewReader("")) + if err == nil { + t.Fatalf("findUserId('notanumber'): got nil error") + } + if want := "user: invalid userid notanumber"; err.Error() != want { + t.Errorf("findUserId('notanumber'): got %v, want %s", err, want) + } +} + +func TestLookupUserId(t *testing.T) { + for _, tt := range userIdTests { + got, err := findUserId(tt.uid, strings.NewReader(tt.in)) + if tt.name == "" { + if err == nil { + t.Errorf("findUserId(%s): got nil error, expected err", tt.uid) + continue + } + switch terr := err.(type) { + case UnknownUserIdError: + if want := "user: unknown userid " + tt.uid; terr.Error() != want { + t.Errorf("findUserId(%s): got %v, want %v", tt.name, terr, want) + } + default: + t.Errorf("findUserId(%s): got unexpected error %v", tt.name, terr) + } + } else { + if err != nil { + t.Fatalf("findUserId(%s): got unexpected error %v", tt.name, err) + } + if got.Uid != tt.uid { + t.Errorf("findUserId(%s): got uid %v, want %s", tt.name, got.Uid, tt.uid) + } + if got.Username != tt.name { + t.Errorf("findUserId(%s): got name %s, want %s", tt.name, got.Username, tt.name) + } + } + } +} + +func TestLookupUserPopulatesAllFields(t *testing.T) { + u, err := findUsername("allfields", strings.NewReader(testUserFile)) + if err != nil { + t.Fatal(err) + } + want := &User{ + Username: "allfields", + Uid: "6", + Gid: "12", + Name: "mansplit", + HomeDir: "/home/allfields", + } + if !reflect.DeepEqual(u, want) { + t.Errorf("findUsername: got %#v, want %#v", u, want) + } +} + +var userTests = []struct { + in string + name string + uid string +}{ + {testUserFile, "negative", "-5"}, + {testUserFile, "bin", "2"}, + {testUserFile, "notinthefile", ""}, + {testUserFile, "indented", "3"}, + {testUserFile, "plussign", ""}, + {testUserFile, "+plussign", ""}, + {testUserFile, "minussign", ""}, + {testUserFile, "-minussign", ""}, + {testUserFile, " indented", ""}, + {testUserFile, "commented", ""}, + {testUserFile, "commentindented", ""}, + {testUserFile, "malformed", ""}, + {testUserFile, "# commented", ""}, + {"", "emptyfile", ""}, +} + +func TestLookupUser(t *testing.T) { + for _, tt := range userTests { + got, err := findUsername(tt.name, strings.NewReader(tt.in)) + if tt.uid == "" { + if err == nil { + t.Errorf("lookupUser(%s): got nil error, expected err", tt.uid) + continue + } + switch terr := err.(type) { + case UnknownUserError: + if want := "user: unknown user " + tt.name; terr.Error() != want { + t.Errorf("lookupUser(%s): got %v, want %v", tt.name, terr, want) + } + default: + t.Errorf("lookupUser(%s): got unexpected error %v", tt.name, terr) + } + } else { + if err != nil { + t.Fatalf("lookupUser(%s): got unexpected error %v", tt.name, err) + } + if got.Uid != tt.uid { + t.Errorf("lookupUser(%s): got uid %v, want %s", tt.name, got.Uid, tt.uid) + } + if got.Username != tt.name { + t.Errorf("lookupUser(%s): got name %s, want %s", tt.name, got.Username, tt.name) + } + } + } +} |