Source file src/os/user/listgroups_unix_test.go

     1  // Copyright 2021 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 ((darwin || dragonfly || freebsd || (js && wasm) || wasip1 || (!android && linux) || netbsd || openbsd || solaris) && ((!cgo && !darwin) || osusergo)) || aix || illumos
     6  
     7  package user
     8  
     9  import (
    10  	"fmt"
    11  	"slices"
    12  	"strings"
    13  	"testing"
    14  )
    15  
    16  var testGroupFile = `# See the opendirectoryd(8) man page for additional
    17  # information about Open Directory.
    18  ##
    19  nobody:*:-2:
    20  nogroup:*:-1:
    21  wheel:*:0:root
    22  emptyid:*::root
    23  invalidgid:*:notanumber:root
    24  +plussign:*:20:root
    25  -minussign:*:21:root
    26  # Next line is invalid (empty group name)
    27  :*:22:root
    28  
    29  daemon:*:1:root
    30      indented:*:7:root
    31  # comment:*:4:found
    32       # comment:*:4:found
    33  kmem:*:2:root
    34  manymembers:x:777:jill,jody,john,jack,jov,user777
    35  ` + largeGroup()
    36  
    37  func largeGroup() (res string) {
    38  	var b strings.Builder
    39  	b.WriteString("largegroup:x:1000:user1")
    40  	for i := 2; i <= 7500; i++ {
    41  		fmt.Fprintf(&b, ",user%d", i)
    42  	}
    43  	return b.String()
    44  }
    45  
    46  var listGroupsTests = []struct {
    47  	// input
    48  	in   string
    49  	user string
    50  	gid  string
    51  	// output
    52  	gids []string
    53  	err  bool
    54  }{
    55  	{in: testGroupFile, user: "root", gid: "0", gids: []string{"0", "1", "2", "7"}},
    56  	{in: testGroupFile, user: "jill", gid: "33", gids: []string{"33", "777"}},
    57  	{in: testGroupFile, user: "jody", gid: "34", gids: []string{"34", "777"}},
    58  	{in: testGroupFile, user: "john", gid: "35", gids: []string{"35", "777"}},
    59  	{in: testGroupFile, user: "jov", gid: "37", gids: []string{"37", "777"}},
    60  	{in: testGroupFile, user: "user777", gid: "7", gids: []string{"7", "777", "1000"}},
    61  	{in: testGroupFile, user: "user1111", gid: "1111", gids: []string{"1111", "1000"}},
    62  	{in: testGroupFile, user: "user1000", gid: "1000", gids: []string{"1000"}},
    63  	{in: testGroupFile, user: "user7500", gid: "7500", gids: []string{"1000", "7500"}},
    64  	{in: testGroupFile, user: "no-such-user", gid: "2345", gids: []string{"2345"}},
    65  	{in: "", user: "no-such-user", gid: "2345", gids: []string{"2345"}},
    66  	// Error cases.
    67  	{in: "", user: "", gid: "2345", err: true},
    68  	{in: "", user: "joanna", gid: "bad", err: true},
    69  }
    70  
    71  func TestListGroups(t *testing.T) {
    72  	for _, tc := range listGroupsTests {
    73  		u := &User{Username: tc.user, Gid: tc.gid}
    74  		got, err := listGroupsFromReader(u, strings.NewReader(tc.in))
    75  		if tc.err {
    76  			if err == nil {
    77  				t.Errorf("listGroups(%q): got nil; want error", tc.user)
    78  			}
    79  			continue // no more checks
    80  		}
    81  		if err != nil {
    82  			t.Errorf("listGroups(%q): got %v error, want nil", tc.user, err)
    83  			continue // no more checks
    84  		}
    85  		checkSameIDs(t, got, tc.gids)
    86  	}
    87  }
    88  
    89  func checkSameIDs(t *testing.T, got, want []string) {
    90  	t.Helper()
    91  	if len(got) != len(want) {
    92  		t.Errorf("ID list mismatch: got %v; want %v", got, want)
    93  		return
    94  	}
    95  	slices.Sort(got)
    96  	slices.Sort(want)
    97  	mismatch := -1
    98  	for i, g := range want {
    99  		if got[i] != g {
   100  			mismatch = i
   101  			break
   102  		}
   103  	}
   104  	if mismatch != -1 {
   105  		t.Errorf("ID list mismatch (at index %d): got %v; want %v", mismatch, got, want)
   106  	}
   107  }
   108  

View as plain text