Adds IsDir and Seek to platform.File (#1441)

Signed-off-by: Adrian Cole <adrian@tetrate.io>
This commit is contained in:
Crypt Keeper
2023-05-09 07:47:25 +08:00
committed by GitHub
parent 99d45623c0
commit 29c7c7667b
18 changed files with 576 additions and 273 deletions

View File

@@ -21,7 +21,7 @@ func TestNewDirFS(t *testing.T) {
// Guest can look up /
f, errno := testFS.OpenFile("/", os.O_RDONLY, 0)
require.EqualErrno(t, 0, errno)
require.Zero(t, f.Close())
require.EqualErrno(t, 0, f.Close())
t.Run("host path not found", func(t *testing.T) {
testFS := NewDirFS("a")
@@ -66,7 +66,7 @@ func TestDirFS_Lstat(t *testing.T) {
testFS := NewDirFS(tmpDir)
for _, path := range []string{"animals.txt", "sub", "sub-link"} {
require.Zero(t, testFS.Symlink(path, path+"-link"))
require.EqualErrno(t, 0, testFS.Symlink(path, path+"-link"))
}
testLstat(t, testFS)
@@ -80,7 +80,7 @@ func TestDirFS_MkDir(t *testing.T) {
realPath := path.Join(tmpDir, name)
t.Run("doesn't exist", func(t *testing.T) {
require.Zero(t, testFS.Mkdir(name, fs.ModeDir))
require.EqualErrno(t, 0, testFS.Mkdir(name, fs.ModeDir))
stat, err := os.Stat(realPath)
require.NoError(t, err)
@@ -131,12 +131,12 @@ func testChmod(t *testing.T, testFS FS, path string) {
requireMode(t, testFS, path, 0o444)
// Test adding write, using 0o666 not 0o600 for read-back on windows.
require.Zero(t, testFS.Chmod(path, 0o666))
require.EqualErrno(t, 0, testFS.Chmod(path, 0o666))
requireMode(t, testFS, path, 0o666)
if runtime.GOOS != "windows" {
// Test clearing group and world, setting owner read+execute.
require.Zero(t, testFS.Chmod(path, 0o500))
require.EqualErrno(t, 0, testFS.Chmod(path, 0o500))
requireMode(t, testFS, path, 0o500)
}
}
@@ -195,7 +195,7 @@ func TestDirFS_Rename(t *testing.T) {
dir2 := "dir2"
dir2Path := path.Join(tmpDir, dir2)
errrno := testFS.Rename(dir1, dir2)
require.Zero(t, errrno)
require.EqualErrno(t, 0, errrno)
// Show the prior path no longer exists
_, err := os.Stat(dir1Path)
@@ -418,7 +418,7 @@ func TestDirFS_Rmdir(t *testing.T) {
name := "rmdir"
realPath := path.Join(tmpDir, name)
require.NoError(t, os.Mkdir(realPath, 0o700))
require.Zero(t, testFS.Rmdir(name))
require.EqualErrno(t, 0, testFS.Rmdir(name))
_, err := os.Stat(realPath)
require.Error(t, err)
})
@@ -433,11 +433,9 @@ func TestDirFS_Rmdir(t *testing.T) {
f, errno := testFS.OpenFile(name, platform.O_DIRECTORY, 0o700)
require.EqualErrno(t, 0, errno)
defer func() {
require.Zero(t, f.Close())
}()
defer f.Close()
require.Zero(t, testFS.Rmdir(name))
require.EqualErrno(t, 0, testFS.Rmdir(name))
_, err := os.Stat(realPath)
require.Error(t, err)
})
@@ -494,7 +492,7 @@ func TestDirFS_Unlink(t *testing.T) {
// Create a symlink to the subdirectory.
const symlinkName = "symlink-to-dir"
require.Zero(t, testFS.Symlink("subdir", symlinkName))
require.EqualErrno(t, 0, testFS.Symlink("subdir", symlinkName))
// Unlinking the symlink should suceed.
errno := testFS.Unlink(symlinkName)
@@ -510,7 +508,7 @@ func TestDirFS_Unlink(t *testing.T) {
require.NoError(t, os.WriteFile(realPath, []byte{}, 0o600))
require.Zero(t, testFS.Unlink(name))
require.EqualErrno(t, 0, testFS.Unlink(name))
_, err := os.Stat(realPath)
require.Error(t, err)

View File

@@ -16,7 +16,7 @@ func TestDirFS_Chown(t *testing.T) {
tmpDir := t.TempDir()
testFS := NewDirFS(tmpDir)
require.Zero(t, testFS.Mkdir("dir", 0o0777))
require.EqualErrno(t, 0, testFS.Mkdir("dir", 0o0777))
dirF, errno := testFS.OpenFile("dir", syscall.O_RDONLY, 0)
require.EqualErrno(t, 0, errno)
@@ -32,12 +32,12 @@ func TestDirFS_Chown(t *testing.T) {
require.NoError(t, err)
t.Run("-1 parameters means leave alone", func(t *testing.T) {
require.Zero(t, testFS.Chown("dir", -1, -1))
require.EqualErrno(t, 0, testFS.Chown("dir", -1, -1))
checkUidGid(t, path.Join(tmpDir, "dir"), dirSys.Uid, dirSys.Gid)
})
t.Run("change gid, but not uid", func(t *testing.T) {
require.Zero(t, testFS.Chown("dir", -1, gid))
require.EqualErrno(t, 0, testFS.Chown("dir", -1, gid))
checkUidGid(t, path.Join(tmpDir, "dir"), dirSys.Uid, uint32(gid))
})
@@ -46,11 +46,11 @@ func TestDirFS_Chown(t *testing.T) {
g := g
t.Run(fmt.Sprintf("change to gid %d", g), func(t *testing.T) {
// Test using our Chown
require.Zero(t, testFS.Chown("dir", -1, g))
require.EqualErrno(t, 0, testFS.Chown("dir", -1, g))
checkUidGid(t, path.Join(tmpDir, "dir"), dirSys.Uid, uint32(g))
// Revert back with File.Chown
require.Zero(t, dirF.Chown(-1, gid))
// Revert back
require.EqualErrno(t, 0, dirF.Chown(-1, gid))
checkUidGid(t, path.Join(tmpDir, "dir"), dirSys.Uid, uint32(gid))
})
}
@@ -64,7 +64,7 @@ func TestDirFS_Lchown(t *testing.T) {
tmpDir := t.TempDir()
testFS := NewDirFS(tmpDir)
require.Zero(t, testFS.Mkdir("dir", 0o0777))
require.EqualErrno(t, 0, testFS.Mkdir("dir", 0o0777))
dirF, errno := testFS.OpenFile("dir", syscall.O_RDONLY, 0)
require.EqualErrno(t, 0, errno)
@@ -73,7 +73,7 @@ func TestDirFS_Lchown(t *testing.T) {
dirSys := dirStat.Sys().(*syscall.Stat_t)
require.Zero(t, testFS.Symlink("dir", "link"))
require.EqualErrno(t, 0, testFS.Symlink("dir", "link"))
linkF, errno := testFS.OpenFile("link", syscall.O_RDONLY, 0)
require.EqualErrno(t, 0, errno)
@@ -89,12 +89,12 @@ func TestDirFS_Lchown(t *testing.T) {
require.NoError(t, err)
t.Run("-1 parameters means leave alone", func(t *testing.T) {
require.Zero(t, testFS.Lchown("link", -1, -1))
require.EqualErrno(t, 0, testFS.Lchown("link", -1, -1))
checkUidGid(t, path.Join(tmpDir, "link"), linkSys.Uid, linkSys.Gid)
})
t.Run("change gid, but not uid", func(t *testing.T) {
require.Zero(t, testFS.Chown("dir", -1, gid))
require.EqualErrno(t, 0, testFS.Chown("dir", -1, gid))
checkUidGid(t, path.Join(tmpDir, "link"), linkSys.Uid, uint32(gid))
// Make sure the target didn't change.
checkUidGid(t, path.Join(tmpDir, "dir"), dirSys.Uid, dirSys.Gid)
@@ -105,13 +105,13 @@ func TestDirFS_Lchown(t *testing.T) {
g := g
t.Run(fmt.Sprintf("change to gid %d", g), func(t *testing.T) {
// Test using our Lchown
require.Zero(t, testFS.Lchown("link", -1, g))
require.EqualErrno(t, 0, testFS.Lchown("link", -1, g))
checkUidGid(t, path.Join(tmpDir, "link"), linkSys.Uid, uint32(g))
// Make sure the target didn't change.
checkUidGid(t, path.Join(tmpDir, "dir"), dirSys.Uid, dirSys.Gid)
// Revert back with syscall.Lchown
require.NoError(t, syscall.Lchown(path.Join(tmpDir, "link"), -1, gid))
// Revert back
require.EqualErrno(t, 0, testFS.Lchown("link", -1, gid))
checkUidGid(t, path.Join(tmpDir, "link"), linkSys.Uid, uint32(gid))
})
}

View File

@@ -41,7 +41,7 @@ func TestReadFS_Lstat(t *testing.T) {
writeable := NewDirFS(tmpDir)
for _, path := range []string{"animals.txt", "sub", "sub-link"} {
require.Zero(t, writeable.Symlink(path, path+"-link"))
require.EqualErrno(t, 0, writeable.Symlink(path, path+"-link"))
}
testFS := NewReadFS(writeable)

View File

@@ -50,7 +50,7 @@ func TestNewRootFS(t *testing.T) {
// Guest can look up /tmp
f, errno := rootFS.OpenFile("/tmp", os.O_RDONLY, 0)
require.EqualErrno(t, 0, errno)
require.Zero(t, f.Close())
require.EqualErrno(t, 0, f.Close())
// Guest can look up / and see "/tmp" in it
f, errno = rootFS.OpenFile("/", os.O_RDONLY, 0)
@@ -283,7 +283,7 @@ func TestRootFS_examples(t *testing.T) {
for _, p := range tc.expected {
f, errno := root.OpenFile(p, os.O_RDONLY, 0)
require.Zero(t, errno, p)
require.Zero(t, f.Close(), p)
require.EqualErrno(t, 0, f.Close(), p)
}
for _, p := range tc.unexpected {

View File

@@ -36,7 +36,7 @@ func testOpen_O_RDWR(t *testing.T, tmpDir string, testFS FS) {
require.NoError(t, err)
require.Equal(t, fileContents, b)
require.Zero(t, f.Close())
require.EqualErrno(t, 0, f.Close())
// re-create as read-only, using 0444 to allow read-back on windows.
require.NoError(t, os.Remove(realPath))
@@ -194,25 +194,24 @@ shark
dinosaur
human
`)
// Ensure it implements io.ReaderAt
r, ok := f.File().(io.ReaderAt)
require.True(t, ok)
// Ensure it implements Pread
lenToRead := len(fileContents) - 1
buf := make([]byte, lenToRead)
n, err := r.ReadAt(buf, 1)
require.NoError(t, err)
n, errno := f.Pread(buf, 1)
require.EqualErrno(t, 0, errno)
require.Equal(t, lenToRead, n)
require.Equal(t, fileContents[1:], buf)
// Ensure it implements io.Seeker
s, ok := f.File().(io.Seeker)
require.True(t, ok)
offset, err := s.Seek(1, io.SeekStart)
require.NoError(t, err)
// Ensure it implements Seek
offset, errno := f.Seek(1, io.SeekStart)
require.EqualErrno(t, 0, errno)
require.Equal(t, int64(1), offset)
b, err := io.ReadAll(f.File())
require.NoError(t, err)
require.Equal(t, fileContents[1:], b)
// Read should pick up from position 1
n, errno = f.Read(buf)
require.EqualErrno(t, 0, errno)
require.Equal(t, lenToRead, n)
require.Equal(t, fileContents[1:], buf)
})
// Make sure O_RDONLY isn't treated bitwise as it is usually zero.
@@ -228,20 +227,20 @@ human
t.Run("writing to a read-only file is EBADF", func(t *testing.T) {
f, errno := testFS.OpenFile("animals.txt", os.O_RDONLY, 0)
defer require.Zero(t, f.Close())
defer f.Close()
require.EqualErrno(t, 0, errno)
_, err := f.Write([]byte{1, 2, 3, 4})
require.EqualErrno(t, syscall.EBADF, platform.UnwrapOSError(err))
_, errno = f.Write([]byte{1, 2, 3, 4})
require.EqualErrno(t, syscall.EBADF, errno)
})
t.Run("writing to a directory is EBADF", func(t *testing.T) {
t.Run("writing to a directory is EISDIR", func(t *testing.T) {
f, errno := testFS.OpenFile("sub", os.O_RDONLY, 0)
defer require.Zero(t, f.Close())
defer f.Close()
require.EqualErrno(t, 0, errno)
_, err := f.Write([]byte{1, 2, 3, 4})
require.EqualErrno(t, syscall.EBADF, platform.UnwrapOSError(err))
_, errno = f.Write([]byte{1, 2, 3, 4})
require.EqualErrno(t, syscall.EISDIR, errno)
})
}