mirror of git://gcc.gnu.org/git/gcc.git
				
				
				
			
		
			
				
	
	
		
			277 lines
		
	
	
		
			7.6 KiB
		
	
	
	
		
			Go
		
	
	
	
			
		
		
	
	
			277 lines
		
	
	
		
			7.6 KiB
		
	
	
	
		
			Go
		
	
	
	
| // 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.
 | |
| 
 | |
| // +build darwin dragonfly freebsd !android,linux nacl netbsd openbsd solaris
 | |
| // +build !cgo
 | |
| 
 | |
| package user
 | |
| 
 | |
| import (
 | |
| 	"reflect"
 | |
| 	"strings"
 | |
| 	"testing"
 | |
| )
 | |
| 
 | |
| const testGroupFile = `# See the opendirectoryd(8) man page for additional 
 | |
| # information about Open Directory.
 | |
| ##
 | |
| nobody:*:-2:
 | |
| nogroup:*:-1:
 | |
| wheel:*:0:root
 | |
| emptyid:*::root
 | |
| invalidgid:*:notanumber:root
 | |
| +plussign:*:20:root
 | |
| -minussign:*:21:root
 | |
|       
 | |
| daemon:*:1:root
 | |
|     indented:*:7:
 | |
| # comment:*:4:found
 | |
|      # comment:*:4:found
 | |
| kmem:*:2:root
 | |
| `
 | |
| 
 | |
| 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", ""},
 | |
| 	{"", "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)
 | |
| 			}
 | |
| 		}
 | |
| 	}
 | |
| }
 |