summaryrefslogtreecommitdiffstats
path: root/src/os/user/lookup_unix_test.go
diff options
context:
space:
mode:
Diffstat (limited to 'src/os/user/lookup_unix_test.go')
-rw-r--r--src/os/user/lookup_unix_test.go259
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)
+ }
+ }
+ }
+}