From: Dave Cheney Date: Wed, 29 Jul 2015 10:06:45 +0000 (+1000) Subject: os: add explicit tests for fchown(2) and lchown(2) on unix platforms X-Git-Tag: go1.5rc1~58 X-Git-Url: http://www.git.cypherpunks.su/?a=commitdiff_plain;h=296529b7341280b8beae2630eff4220fa6c1ac2b;p=gostls13.git os: add explicit tests for fchown(2) and lchown(2) on unix platforms Fixes #11919 Issue #11918 suggested that os.File.Chown and os.Lchown were under tested. Change-Id: Ib41f7cb2d2fe0066d2ccb4d1bdabe1795efe80fc Reviewed-on: https://go-review.googlesource.com/12834 Reviewed-by: Russ Cox Run-TryBot: Russ Cox TryBot-Result: Gobot Gobot --- diff --git a/src/os/os_unix_test.go b/src/os/os_unix_test.go index afee189650..2adc3b50e7 100644 --- a/src/os/os_unix_test.go +++ b/src/os/os_unix_test.go @@ -32,10 +32,10 @@ func checkUidGid(t *testing.T, path string, uid, gid int) { } func TestChown(t *testing.T) { - // Chown is not supported under windows os Plan 9. + // Chown is not supported under windows or Plan 9. // Plan9 provides a native ChownPlan9 version instead. if runtime.GOOS == "windows" || runtime.GOOS == "plan9" { - return + t.Skipf("%s does not support syscall.Chown", runtime.GOOS) } // Use TempDir() to make sure we're on a local file system, // so that the group ids returned by Getgroups will be allowed @@ -78,3 +78,109 @@ func TestChown(t *testing.T) { checkUidGid(t, f.Name(), int(sys.Uid), gid) } } + +func TestFileChown(t *testing.T) { + // Fchown is not supported under windows or Plan 9. + if runtime.GOOS == "windows" || runtime.GOOS == "plan9" { + t.Skipf("%s does not support syscall.Fchown", runtime.GOOS) + } + // Use TempDir() to make sure we're on a local file system, + // so that the group ids returned by Getgroups will be allowed + // on the file. On NFS, the Getgroups groups are + // basically useless. + f := newFile("TestFileChown", t) + defer Remove(f.Name()) + defer f.Close() + dir, err := f.Stat() + if err != nil { + t.Fatalf("stat %s: %s", f.Name(), err) + } + + // Can't change uid unless root, but can try + // changing the group id. First try our current group. + gid := Getgid() + t.Log("gid:", gid) + if err = f.Chown(-1, gid); err != nil { + t.Fatalf("fchown %s -1 %d: %s", f.Name(), gid, err) + } + sys := dir.Sys().(*syscall.Stat_t) + checkUidGid(t, f.Name(), int(sys.Uid), gid) + + // Then try all the auxiliary groups. + groups, err := Getgroups() + if err != nil { + t.Fatalf("getgroups: %s", err) + } + t.Log("groups: ", groups) + for _, g := range groups { + if err = f.Chown(-1, g); err != nil { + t.Fatalf("fchown %s -1 %d: %s", f.Name(), g, err) + } + checkUidGid(t, f.Name(), int(sys.Uid), g) + + // change back to gid to test fd.Chown + if err = f.Chown(-1, gid); err != nil { + t.Fatalf("fchown %s -1 %d: %s", f.Name(), gid, err) + } + checkUidGid(t, f.Name(), int(sys.Uid), gid) + } +} + +func TestLchown(t *testing.T) { + // Lchown is not supported under windows or Plan 9. + if runtime.GOOS == "windows" || runtime.GOOS == "plan9" { + t.Skipf("%s does not support syscall.Lchown", runtime.GOOS) + } + // Use TempDir() to make sure we're on a local file system, + // so that the group ids returned by Getgroups will be allowed + // on the file. On NFS, the Getgroups groups are + // basically useless. + f := newFile("TestLchown", t) + defer Remove(f.Name()) + defer f.Close() + dir, err := f.Stat() + if err != nil { + t.Fatalf("stat %s: %s", f.Name(), err) + } + + linkname := f.Name() + "2" + if err := Link(f.Name(), linkname); err != nil { + t.Fatalf("link %s -> %s: %v", f.Name(), linkname, err) + } + defer Remove(linkname) + + f2, err := Open(linkname) + if err != nil { + t.Fatalf("open %s: %v", linkname, err) + } + defer f2.Close() + + // Can't change uid unless root, but can try + // changing the group id. First try our current group. + gid := Getgid() + t.Log("gid:", gid) + if err = Lchown(linkname, -1, gid); err != nil { + t.Fatalf("lchown %s -1 %d: %s", linkname, gid, err) + } + sys := dir.Sys().(*syscall.Stat_t) + checkUidGid(t, linkname, int(sys.Uid), gid) + + // Then try all the auxiliary groups. + groups, err := Getgroups() + if err != nil { + t.Fatalf("getgroups: %s", err) + } + t.Log("groups: ", groups) + for _, g := range groups { + if err = Lchown(linkname, -1, g); err != nil { + t.Fatalf("lchown %s -1 %d: %s", linkname, g, err) + } + checkUidGid(t, linkname, int(sys.Uid), g) + + // change back to gid to test fd.Chown + if err = f2.Chown(-1, gid); err != nil { + t.Fatalf("fchown %s -1 %d: %s", linkname, gid, err) + } + checkUidGid(t, linkname, int(sys.Uid), gid) + } +}