mirror of
https://github.com/golang/sys.git
synced 2026-01-29 07:02:06 +03:00
This removes the remaining (and trivial) use of deprecated ioutil package from test files. Replacements are easy: ioutil.ReadAll -> io.ReadAll ioutil.ReadDir -> os.ReadDir ioutil.ReadFile -> os.ReadFile ioutil.WriteFile -> os.WriteFile While at it, simplify some error reporting. Change-Id: I60a242fd3c08d8fe571a18f16716439a9acdd59d Reviewed-on: https://go-review.googlesource.com/c/sys/+/526299 LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com> Reviewed-by: Heschi Kreinick <heschi@google.com> Reviewed-by: Ian Lance Taylor <iant@google.com> Run-TryBot: Kirill Kolyshkin <kolyshkin@gmail.com> TryBot-Result: Gopher Robot <gobot@golang.org> Auto-Submit: Tobias Klauser <tobias.klauser@gmail.com>
265 lines
6.0 KiB
Go
265 lines
6.0 KiB
Go
// 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
|
|
|
|
import (
|
|
"bytes"
|
|
"net"
|
|
"os"
|
|
"path/filepath"
|
|
"testing"
|
|
|
|
"golang.org/x/sys/unix"
|
|
)
|
|
|
|
var testData = []byte("This is a test\n")
|
|
|
|
// 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
|
|
}
|
|
|
|
func createTestFile(t *testing.T) string {
|
|
filename := filepath.Join(t.TempDir(), t.Name())
|
|
err := os.WriteFile(filename, testData, 0600)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
return filename
|
|
}
|
|
|
|
func TestClonefile(t *testing.T) {
|
|
fileName := createTestFile(t)
|
|
|
|
clonedName := fileName + "-cloned"
|
|
err := unix.Clonefile(fileName, clonedName, 0)
|
|
if err == unix.ENOSYS || err == unix.ENOTSUP {
|
|
t.Skip("clonefile is not available or supported, skipping test")
|
|
} else if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
clonedData, err := os.ReadFile(clonedName)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
if !bytes.Equal(testData, clonedData) {
|
|
t.Errorf("Clonefile: got %q, expected %q", clonedData, testData)
|
|
}
|
|
}
|
|
|
|
func TestClonefileatWithCwd(t *testing.T) {
|
|
fileName := createTestFile(t)
|
|
|
|
clonedName := fileName + "-cloned"
|
|
err := unix.Clonefileat(unix.AT_FDCWD, fileName, unix.AT_FDCWD, clonedName, 0)
|
|
if err == unix.ENOSYS || err == unix.ENOTSUP {
|
|
t.Skip("clonefileat is not available or supported, skipping test")
|
|
} else if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
clonedData, err := os.ReadFile(clonedName)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
if !bytes.Equal(testData, clonedData) {
|
|
t.Errorf("Clonefileat: got %q, expected %q", clonedData, testData)
|
|
}
|
|
}
|
|
|
|
func TestClonefileatWithRelativePaths(t *testing.T) {
|
|
srcFileName := createTestFile(t)
|
|
srcDir := filepath.Dir(srcFileName)
|
|
srcFd, err := unix.Open(srcDir, unix.O_RDONLY|unix.O_DIRECTORY, 0)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
defer unix.Close(srcFd)
|
|
|
|
dstDir := t.TempDir()
|
|
dstFd, err := unix.Open(dstDir, unix.O_RDONLY|unix.O_DIRECTORY, 0)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
defer unix.Close(dstFd)
|
|
|
|
dstFile, err := os.Create(filepath.Join(dstDir, "TestClonefileat"))
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
err = os.Remove(dstFile.Name())
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
src := filepath.Base(srcFileName)
|
|
dst := filepath.Base(dstFile.Name())
|
|
err = unix.Clonefileat(srcFd, src, dstFd, dst, 0)
|
|
if err == unix.ENOSYS || err == unix.ENOTSUP {
|
|
t.Skip("clonefileat is not available or supported, skipping test")
|
|
} else if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
clonedData, err := os.ReadFile(dstFile.Name())
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
if !bytes.Equal(testData, clonedData) {
|
|
t.Errorf("Clonefileat: got %q, expected %q", clonedData, testData)
|
|
}
|
|
}
|
|
|
|
func TestFclonefileat(t *testing.T) {
|
|
fileName := createTestFile(t)
|
|
dir := filepath.Dir(fileName)
|
|
|
|
fd, err := unix.Open(fileName, unix.O_RDONLY, 0)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
defer unix.Close(fd)
|
|
|
|
dstFile, err := os.Create(filepath.Join(dir, "dst"))
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
os.Remove(dstFile.Name())
|
|
|
|
err = unix.Fclonefileat(fd, unix.AT_FDCWD, dstFile.Name(), 0)
|
|
if err == unix.ENOSYS || err == unix.ENOTSUP {
|
|
t.Skip("clonefileat is not available or supported, skipping test")
|
|
} else if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
clonedData, err := os.ReadFile(dstFile.Name())
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
if !bytes.Equal(testData, clonedData) {
|
|
t.Errorf("Fclonefileat: got %q, expected %q", clonedData, testData)
|
|
}
|
|
}
|
|
|
|
func TestFcntlFstore(t *testing.T) {
|
|
f, err := os.CreateTemp(t.TempDir(), t.Name())
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
defer f.Close()
|
|
|
|
fstore := &unix.Fstore_t{
|
|
Flags: unix.F_ALLOCATEALL,
|
|
Posmode: unix.F_PEOFPOSMODE,
|
|
Offset: 0,
|
|
Length: 1 << 10,
|
|
}
|
|
err = unix.FcntlFstore(f.Fd(), unix.F_PREALLOCATE, fstore)
|
|
if err == unix.EOPNOTSUPP {
|
|
t.Skipf("fcntl with F_PREALLOCATE not supported, skipping test")
|
|
} else if err != nil {
|
|
t.Fatalf("FcntlFstore: %v", err)
|
|
}
|
|
|
|
st, err := f.Stat()
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
if st.Size() != 0 {
|
|
t.Errorf("FcntlFstore: got size = %d, want %d", st.Size(), 0)
|
|
}
|
|
|
|
}
|
|
|
|
func TestGetsockoptXucred(t *testing.T) {
|
|
fds, err := unix.Socketpair(unix.AF_LOCAL, unix.SOCK_STREAM, 0)
|
|
if err != nil {
|
|
t.Fatalf("Socketpair: %v", err)
|
|
}
|
|
|
|
srvFile := os.NewFile(uintptr(fds[0]), "server")
|
|
cliFile := os.NewFile(uintptr(fds[1]), "client")
|
|
defer srvFile.Close()
|
|
defer cliFile.Close()
|
|
|
|
srv, err := net.FileConn(srvFile)
|
|
if err != nil {
|
|
t.Fatalf("FileConn: %v", err)
|
|
}
|
|
defer srv.Close()
|
|
|
|
cli, err := net.FileConn(cliFile)
|
|
if err != nil {
|
|
t.Fatalf("FileConn: %v", err)
|
|
}
|
|
defer cli.Close()
|
|
|
|
cred, err := unix.GetsockoptXucred(fds[1], unix.SOL_LOCAL, unix.LOCAL_PEERCRED)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
t.Logf("got: %+v", cred)
|
|
if got, want := cred.Uid, os.Getuid(); int(got) != int(want) {
|
|
t.Errorf("uid = %v; want %v", got, want)
|
|
}
|
|
if cred.Ngroups > 0 {
|
|
if got, want := cred.Groups[0], os.Getgid(); int(got) != int(want) {
|
|
t.Errorf("gid = %v; want %v", got, want)
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestSysctlKinfoProc(t *testing.T) {
|
|
pid := unix.Getpid()
|
|
kp, err := unix.SysctlKinfoProc("kern.proc.pid", pid)
|
|
if err != nil {
|
|
t.Fatalf("SysctlKinfoProc: %v", err)
|
|
}
|
|
if got, want := int(kp.Proc.P_pid), pid; got != want {
|
|
t.Errorf("got pid %d, want %d", got, want)
|
|
}
|
|
}
|
|
|
|
func TestSysctlKinfoProcSlice(t *testing.T) {
|
|
kps, err := unix.SysctlKinfoProcSlice("kern.proc.all")
|
|
if err != nil {
|
|
t.Fatalf("SysctlKinfoProc: %v", err)
|
|
}
|
|
if len(kps) == 0 {
|
|
t.Errorf("SysctlKinfoProcSlice: expected at least one process")
|
|
}
|
|
|
|
uid := unix.Getuid()
|
|
kps, err = unix.SysctlKinfoProcSlice("kern.proc.uid", uid)
|
|
if err != nil {
|
|
t.Fatalf("SysctlKinfoProc: %v", err)
|
|
}
|
|
if len(kps) == 0 {
|
|
t.Errorf("SysctlKinfoProcSlice: expected at least one process")
|
|
}
|
|
|
|
for _, kp := range kps {
|
|
if got, want := int(kp.Eproc.Ucred.Uid), uid; got != want {
|
|
t.Errorf("process %d: got uid %d, want %d", kp.Proc.P_pid, got, want)
|
|
}
|
|
}
|
|
}
|