github.com/tetratelabs/wazero@v1.2.1/internal/sysfs/open_file_test.go (about)

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