Procházet zdrojové kódy

unix: add tests for *xattr functions

Based on the tests in github.com/pkg/xattr

Change-Id: I3af73ad538877da042602708248063c218260a2e
Reviewed-on: https://go-review.googlesource.com/114135
Run-TryBot: Tobias Klauser <tobias.klauser@gmail.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
Tobias Klauser před 7 roky
rodič
revize
88eb85aaee

+ 19 - 0
unix/syscall_darwin_test.go

@@ -0,0 +1,19 @@
+// Copyright 2018 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.
+
+package unix_test
+
+// stringsFromByteSlice converts a sequence of attributes to a []string.
+// On Darwin, each entry is a NULL-terminated string.
+func stringsFromByteSlice(buf []byte) []string {
+	var result []string
+	off := 0
+	for i, b := range buf {
+		if b == 0 {
+			result = append(result, string(buf[off:i]))
+			off = i + 1
+		}
+	}
+	return result
+}

+ 15 - 0
unix/syscall_freebsd_test.go

@@ -295,3 +295,18 @@ func TestCapRightsSetAndClear(t *testing.T) {
 		t.Fatalf("Wrong rights set")
 	}
 }
+
+// stringsFromByteSlice converts a sequence of attributes to a []string.
+// On FreeBSD, each entry consists of a single byte containing the length
+// of the attribute name, followed by the attribute name.
+// The name is _not_ NULL-terminated.
+func stringsFromByteSlice(buf []byte) []string {
+	var result []string
+	i := 0
+	for i < len(buf) {
+		next := i + 1 + int(buf[i])
+		result = append(result, string(buf[i+1:next]))
+		i = next
+	}
+	return result
+}

+ 14 - 0
unix/syscall_linux_test.go

@@ -371,3 +371,17 @@ func TestStatx(t *testing.T) {
 		t.Errorf("Statx: returned stat mtime does not match Lstat")
 	}
 }
+
+// stringsFromByteSlice converts a sequence of attributes to a []string.
+// On Linux, each entry is a NULL-terminated string.
+func stringsFromByteSlice(buf []byte) []string {
+	var result []string
+	off := 0
+	for i, b := range buf {
+		if b == 0 {
+			result = append(result, string(buf[off:i]))
+			off = i + 1
+		}
+	}
+	return result
+}

+ 92 - 0
unix/xattr_test.go

@@ -0,0 +1,92 @@
+// Copyright 2018 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 freebsd linux
+
+package unix_test
+
+import (
+	"runtime"
+	"strings"
+	"testing"
+
+	"golang.org/x/sys/unix"
+)
+
+func TestXattr(t *testing.T) {
+	defer chtmpdir(t)()
+
+	f := "xattr1"
+	touch(t, f)
+
+	xattrName := "user.test"
+	xattrDataSet := "gopher"
+	err := unix.Setxattr(f, xattrName, []byte(xattrDataSet), 0)
+	if err == unix.ENOTSUP || err == unix.EOPNOTSUPP {
+		t.Skip("filesystem does not support extended attributes, skipping test")
+	} else if err != nil {
+		t.Fatalf("Setxattr: %v", err)
+	}
+
+	// find size
+	size, err := unix.Listxattr(f, nil)
+	if err != nil {
+		t.Fatalf("Listxattr: %v", err)
+	}
+
+	if size <= 0 {
+		t.Fatalf("Listxattr returned an empty list of attributes")
+	}
+
+	buf := make([]byte, size)
+	read, err := unix.Listxattr(f, buf)
+	if err != nil {
+		t.Fatalf("Listxattr: %v", err)
+	}
+
+	xattrs := stringsFromByteSlice(buf[:read])
+
+	xattrWant := xattrName
+	if runtime.GOOS == "freebsd" {
+		// On FreeBSD, the namespace is stored separately from the xattr
+		// name and Listxattr doesn't return the namespace prefix.
+		xattrWant = strings.TrimPrefix(xattrWant, "user.")
+	}
+	found := false
+	for _, name := range xattrs {
+		if name == xattrWant {
+			found = true
+		}
+	}
+
+	if !found {
+		t.Errorf("Listxattr did not return previously set attribute '%s'", xattrName)
+	}
+
+	// find size
+	size, err = unix.Getxattr(f, xattrName, nil)
+	if err != nil {
+		t.Fatalf("Getxattr: %v", err)
+	}
+
+	if size <= 0 {
+		t.Fatalf("Getxattr returned an empty attribute")
+	}
+
+	xattrDataGet := make([]byte, size)
+	_, err = unix.Getxattr(f, xattrName, xattrDataGet)
+	if err != nil {
+		t.Fatalf("Getxattr: %v", err)
+	}
+
+	got := string(xattrDataGet)
+	if got != xattrDataSet {
+		t.Errorf("Getxattr: expected attribute value %s, got %s", xattrDataSet, got)
+	}
+
+	err = unix.Removexattr(f, xattrName)
+	if err != nil {
+		t.Fatalf("Removexattr: %v", err)
+	}
+}