]> Cypherpunks repositories - gostls13.git/commitdiff
os: add explicit tests for fchown(2) and lchown(2) on unix platforms
authorDave Cheney <dave@cheney.net>
Wed, 29 Jul 2015 10:06:45 +0000 (20:06 +1000)
committerRuss Cox <rsc@golang.org>
Fri, 31 Jul 2015 19:41:42 +0000 (19:41 +0000)
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 <rsc@golang.org>
Run-TryBot: Russ Cox <rsc@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>

src/os/os_unix_test.go

index afee189650c0cc3afb7532cecdf90179b9b43b48..2adc3b50e727cdb5952d5c39c3cb009cb971390f 100644 (file)
@@ -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)
+       }
+}