github.com/bananabytelabs/wazero@v0.0.0-20240105073314-54b22a776da8/internal/sysfs/open_file_test.go (about) 1 package sysfs 2 3 import ( 4 "os" 5 path "path/filepath" 6 "runtime" 7 "testing" 8 9 "github.com/bananabytelabs/wazero/experimental/sys" 10 "github.com/bananabytelabs/wazero/internal/testing/require" 11 ) 12 13 func TestOpenFile(t *testing.T) { 14 tmpDir := t.TempDir() 15 16 t.Run("directory with a trailing slash", func(t *testing.T) { 17 path := path.Join(tmpDir, "dir", "nested") 18 err := os.MkdirAll(path, 0o700) 19 require.NoError(t, err) 20 21 f, errno := OpenFile(path+"/", sys.O_RDONLY, 0) 22 require.EqualErrno(t, 0, errno) 23 require.NoError(t, f.Close()) 24 }) 25 26 // from os.TestDirFSPathsValid 27 if runtime.GOOS != "windows" { 28 t.Run("strange name", func(t *testing.T) { 29 f, errno := OpenFile(path.Join(tmpDir, `e:xperi\ment.txt`), sys.O_WRONLY|sys.O_CREAT|sys.O_TRUNC, 0o600) 30 require.EqualErrno(t, 0, errno) 31 require.NoError(t, f.Close()) 32 }) 33 } 34 } 35 36 func TestOpenFile_Errors(t *testing.T) { 37 tmpDir := t.TempDir() 38 39 t.Run("file with a trailing slash is ENOTDIR", func(t *testing.T) { 40 nested := path.Join(tmpDir, "dir", "nested") 41 err := os.MkdirAll(nested, 0o700) 42 require.NoError(t, err) 43 44 nestedFile := path.Join(nested, "file") 45 err = os.WriteFile(nestedFile, nil, 0o700) 46 require.NoError(t, err) 47 48 _, errno := OpenFile(nestedFile+"/", sys.O_RDONLY, 0) 49 require.EqualErrno(t, sys.ENOTDIR, errno) 50 }) 51 52 t.Run("not found must be ENOENT", func(t *testing.T) { 53 _, errno := OpenFile(path.Join(tmpDir, "not-really-exist.txt"), sys.O_RDONLY, 0o600) 54 require.EqualErrno(t, sys.ENOENT, errno) 55 }) 56 57 // This is the same as https://github.com/ziglang/zig/blob/d24ebf1d12cf66665b52136a2807f97ff021d78d/lib/std/os/test.zig#L105-L112 58 t.Run("try creating on existing file must be EEXIST", func(t *testing.T) { 59 filepath := path.Join(tmpDir, "file.txt") 60 f, errno := OpenFile(filepath, sys.O_RDWR|sys.O_CREAT|sys.O_EXCL, 0o666) 61 require.EqualErrno(t, 0, errno) 62 defer f.Close() 63 64 _, err := OpenFile(filepath, sys.O_RDWR|sys.O_CREAT|sys.O_EXCL, 0o666) 65 require.EqualErrno(t, sys.EEXIST, err) 66 }) 67 68 t.Run("writing to a read-only file is EBADF", func(t *testing.T) { 69 path := path.Join(tmpDir, "file") 70 require.NoError(t, os.WriteFile(path, nil, 0o600)) 71 72 f := requireOpenFile(t, path, sys.O_RDONLY, 0) 73 defer f.Close() 74 75 _, errno := f.Write([]byte{1, 2, 3, 4}) 76 require.EqualErrno(t, sys.EBADF, errno) 77 }) 78 79 t.Run("writing to a directory is EISDIR", func(t *testing.T) { 80 path := path.Join(tmpDir, "diragain") 81 require.NoError(t, os.Mkdir(path, 0o755)) 82 83 f := requireOpenFile(t, path, sys.O_RDONLY, 0) 84 defer f.Close() 85 86 _, errno := f.Write([]byte{1, 2, 3, 4}) 87 require.EqualErrno(t, sys.EISDIR, errno) 88 }) 89 90 // This is similar to https://github.com/WebAssembly/wasi-testsuite/blob/dc7f8d27be1030cd4788ebdf07d9b57e5d23441e/tests/rust/src/bin/dangling_symlink.rs 91 t.Run("dangling symlinks", func(t *testing.T) { 92 target := path.Join(tmpDir, "target") 93 symlink := path.Join(tmpDir, "dangling_symlink_symlink.cleanup") 94 95 err := os.Symlink(target, symlink) 96 require.NoError(t, err) 97 98 _, errno := OpenFile(symlink, sys.O_DIRECTORY|sys.O_NOFOLLOW, 0o0666) 99 require.EqualErrno(t, sys.ENOTDIR, errno) 100 101 _, errno = OpenFile(symlink, sys.O_NOFOLLOW, 0o0666) 102 require.EqualErrno(t, sys.ELOOP, errno) 103 }) 104 105 t.Run("opening a directory writeable is EISDIR", func(t *testing.T) { 106 _, errno := OpenFile(tmpDir, sys.O_DIRECTORY|sys.O_WRONLY, 0o0666) 107 require.EqualErrno(t, sys.EISDIR, errno) 108 109 _, errno = OpenFile(tmpDir, sys.O_DIRECTORY|sys.O_WRONLY, 0o0666) 110 require.EqualErrno(t, sys.EISDIR, errno) 111 }) 112 }