]> go.fuhry.dev Git - fsnotify.git/commitdiff
Check privileges for symlink tests on Windows (#530)
authormattn <mattn.jp@gmail.com>
Thu, 20 Oct 2022 02:22:52 +0000 (11:22 +0900)
committerGitHub <noreply@github.com>
Thu, 20 Oct 2022 02:22:52 +0000 (04:22 +0200)
Tests for symlink always fail when run the tests as non-admin users on Windows since Windows require privileges to create symlinks. This CL change to check the privileges.

fsnotify_test.go
internal/unix2.go [new file with mode: 0644]
internal/windows.go

index 16431f5b20ea292e057196a390a7c40492914af8..beb2c62d7a661d49b95f8ce4288a4fd2a1f3887a 100644 (file)
@@ -166,6 +166,9 @@ func TestWatch(t *testing.T) {
                                // behaviour too.
                                t.Skip("broken on macOS")
                        }
+                       if !internal.HasPrivilegesForSymlink() {
+                               t.Skip("does not have privileges for symlink on this OS")
+                       }
 
                        file := join(tmp, "file")
                        link := join(tmp, "link")
@@ -195,6 +198,9 @@ func TestWatch(t *testing.T) {
                                // behaviour too.
                                t.Skip("broken on macOS")
                        }
+                       if !internal.HasPrivilegesForSymlink() {
+                               t.Skip("does not have privileges for symlink on this OS")
+                       }
 
                        dir := join(tmp, "dir")
                        link := join(tmp, "link")
@@ -246,6 +252,9 @@ func TestWatchCreate(t *testing.T) {
 
                // Links
                {"create new symlink to file", func(t *testing.T, w *Watcher, tmp string) {
+                       if !internal.HasPrivilegesForSymlink() {
+                               t.Skip("does not have privileges for symlink on this OS")
+                       }
                        touch(t, tmp, "file")
                        addWatch(t, w, tmp)
                        symlink(t, join(tmp, "file"), tmp, "link")
@@ -253,6 +262,9 @@ func TestWatchCreate(t *testing.T) {
                        create  /link
                `},
                {"create new symlink to directory", func(t *testing.T, w *Watcher, tmp string) {
+                       if !internal.HasPrivilegesForSymlink() {
+                               t.Skip("does not have privileges for symlink on this OS")
+                       }
                        addWatch(t, w, tmp)
                        symlink(t, tmp, tmp, "link")
                }, `
@@ -505,6 +517,10 @@ func TestWatchRename(t *testing.T) {
 }
 
 func TestWatchSymlink(t *testing.T) {
+       if !internal.HasPrivilegesForSymlink() {
+               t.Skip("does not have privileges for symlink on this OS")
+       }
+
        tests := []testCase{
                {"create unresolvable symlink", func(t *testing.T, w *Watcher, tmp string) {
                        addWatch(t, w, tmp)
diff --git a/internal/unix2.go b/internal/unix2.go
new file mode 100644 (file)
index 0000000..dc40459
--- /dev/null
@@ -0,0 +1,8 @@
+//go:build !windows
+// +build !windows
+
+package internal
+
+func HasPrivilegesForSymlink() bool {
+       return true
+}
index 0e9b3b23869e4583cd34a367cb28a8f2144aa15d..62d1d17b234991f2dc4f11defef5f9dd9619bb80 100644 (file)
@@ -5,6 +5,8 @@ package internal
 
 import (
        "errors"
+
+       "golang.org/x/sys/windows"
 )
 
 // Just a dummy.
@@ -17,3 +19,24 @@ func SetRlimit()                                    {}
 func Maxfiles() uint64                              { return 1<<64 - 1 }
 func Mkfifo(path string, mode uint32) error         { return errors.New("no FIFOs on Windows") }
 func Mknod(path string, mode uint32, dev int) error { return errors.New("no device nodes on Windows") }
+
+func HasPrivilegesForSymlink() bool {
+       var sid *windows.SID
+       err := windows.AllocateAndInitializeSid(
+               &windows.SECURITY_NT_AUTHORITY,
+               2,
+               windows.SECURITY_BUILTIN_DOMAIN_RID,
+               windows.DOMAIN_ALIAS_RID_ADMINS,
+               0, 0, 0, 0, 0, 0,
+               &sid)
+       if err != nil {
+               return false
+       }
+       defer windows.FreeSid(sid)
+       token := windows.Token(0)
+       member, err := token.IsMember(sid)
+       if err != nil {
+               return false
+       }
+       return member || token.IsElevated()
+}