github.com/bananabytelabs/wazero@v0.0.0-20240105073314-54b22a776da8/internal/sysfs/readfs_test.go (about)

     1  package sysfs
     2  
     3  import (
     4  	"io/fs"
     5  	"os"
     6  	"runtime"
     7  	"testing"
     8  
     9  	"github.com/bananabytelabs/wazero/experimental/sys"
    10  	"github.com/bananabytelabs/wazero/internal/fstest"
    11  	"github.com/bananabytelabs/wazero/internal/testing/require"
    12  )
    13  
    14  func TestNewReadFS(t *testing.T) {
    15  	tmpDir := t.TempDir()
    16  
    17  	// Wraps a sys.FS because it allows access to Write
    18  	adapted := &AdaptFS{FS: os.DirFS(tmpDir)}
    19  	require.NotEqual(t, adapted, &ReadFS{FS: adapted})
    20  
    21  	// Wraps a writeable file system
    22  	writeable := DirFS(tmpDir)
    23  	readFS := &ReadFS{FS: writeable}
    24  	require.NotEqual(t, writeable, readFS)
    25  }
    26  
    27  func TestReadFS_Lstat(t *testing.T) {
    28  	tmpDir := t.TempDir()
    29  	require.NoError(t, fstest.WriteTestFiles(tmpDir))
    30  
    31  	writeable := DirFS(tmpDir)
    32  	for _, path := range []string{"animals.txt", "sub", "sub-link"} {
    33  		require.EqualErrno(t, 0, writeable.Symlink(path, path+"-link"))
    34  	}
    35  
    36  	testFS := &ReadFS{FS: writeable}
    37  
    38  	testLstat(t, testFS)
    39  }
    40  
    41  func TestReadFS_MkDir(t *testing.T) {
    42  	writeable := DirFS(t.TempDir())
    43  	testFS := &ReadFS{FS: writeable}
    44  
    45  	err := testFS.Mkdir("mkdir", fs.ModeDir)
    46  	require.EqualErrno(t, sys.EROFS, err)
    47  }
    48  
    49  func TestReadFS_Chmod(t *testing.T) {
    50  	writeable := DirFS(t.TempDir())
    51  	testFS := &ReadFS{FS: writeable}
    52  
    53  	err := testFS.Chmod("chmod", fs.ModeDir)
    54  	require.EqualErrno(t, sys.EROFS, err)
    55  }
    56  
    57  func TestReadFS_Rename(t *testing.T) {
    58  	tmpDir := t.TempDir()
    59  	writeable := DirFS(tmpDir)
    60  	testFS := &ReadFS{FS: writeable}
    61  
    62  	file1 := "file1"
    63  	file1Path := joinPath(tmpDir, file1)
    64  	file1Contents := []byte{1}
    65  	err := os.WriteFile(file1Path, file1Contents, 0o600)
    66  	require.NoError(t, err)
    67  
    68  	file2 := "file2"
    69  	file2Path := joinPath(tmpDir, file2)
    70  	file2Contents := []byte{2}
    71  	err = os.WriteFile(file2Path, file2Contents, 0o600)
    72  	require.NoError(t, err)
    73  
    74  	err = testFS.Rename(file1, file2)
    75  	require.EqualErrno(t, sys.EROFS, err)
    76  }
    77  
    78  func TestReadFS_Rmdir(t *testing.T) {
    79  	tmpDir := t.TempDir()
    80  	writeable := DirFS(tmpDir)
    81  	testFS := &ReadFS{FS: writeable}
    82  
    83  	path := "rmdir"
    84  	realPath := joinPath(tmpDir, path)
    85  	require.NoError(t, os.Mkdir(realPath, 0o700))
    86  
    87  	err := testFS.Rmdir(path)
    88  	require.EqualErrno(t, sys.EROFS, err)
    89  }
    90  
    91  func TestReadFS_Unlink(t *testing.T) {
    92  	tmpDir := t.TempDir()
    93  	writeable := DirFS(tmpDir)
    94  	testFS := &ReadFS{FS: writeable}
    95  
    96  	path := "unlink"
    97  	realPath := joinPath(tmpDir, path)
    98  	require.NoError(t, os.WriteFile(realPath, []byte{}, 0o600))
    99  
   100  	err := testFS.Unlink(path)
   101  	require.EqualErrno(t, sys.EROFS, err)
   102  }
   103  
   104  func TestReadFS_UtimesNano(t *testing.T) {
   105  	tmpDir := t.TempDir()
   106  	writeable := DirFS(tmpDir)
   107  	testFS := &ReadFS{FS: writeable}
   108  
   109  	path := "utimes"
   110  	realPath := joinPath(tmpDir, path)
   111  	require.NoError(t, os.WriteFile(realPath, []byte{}, 0o600))
   112  
   113  	err := testFS.Utimens(path, sys.UTIME_OMIT, sys.UTIME_OMIT)
   114  	require.EqualErrno(t, sys.EROFS, err)
   115  }
   116  
   117  func TestReadFS_Open_Read(t *testing.T) {
   118  	type test struct {
   119  		name          string
   120  		fs            func(tmpDir string) sys.FS
   121  		expectFileIno bool
   122  		expectDirIno  bool
   123  	}
   124  
   125  	tests := []test{
   126  		{
   127  			name: "DirFS",
   128  			fs: func(tmpDir string) sys.FS {
   129  				return DirFS(tmpDir)
   130  			},
   131  			expectFileIno: true,
   132  			expectDirIno:  true,
   133  		},
   134  		{
   135  			name: "fstest.MapFS",
   136  			fs: func(tmpDir string) sys.FS {
   137  				return &AdaptFS{FS: fstest.FS}
   138  			},
   139  			expectFileIno: false,
   140  			expectDirIno:  false,
   141  		},
   142  		{
   143  			name: "os.DirFS",
   144  			fs: func(tmpDir string) sys.FS {
   145  				return &AdaptFS{FS: os.DirFS(tmpDir)}
   146  			},
   147  			expectFileIno: statSetsIno(),
   148  			expectDirIno:  runtime.GOOS != "windows",
   149  		},
   150  		{
   151  			name: "mask(os.DirFS)",
   152  			fs: func(tmpDir string) sys.FS {
   153  				return &AdaptFS{FS: &MaskOsFS{Fs: os.DirFS(tmpDir)}}
   154  			},
   155  			expectFileIno: statSetsIno(),
   156  			expectDirIno:  runtime.GOOS != "windows",
   157  		},
   158  		{
   159  			name: "mask(os.DirFS) ZeroIno",
   160  			fs: func(tmpDir string) sys.FS {
   161  				return &AdaptFS{FS: &MaskOsFS{Fs: os.DirFS(tmpDir), ZeroIno: true}}
   162  			},
   163  			expectFileIno: false,
   164  			expectDirIno:  false,
   165  		},
   166  	}
   167  
   168  	for _, tc := range tests {
   169  		tc := tc
   170  
   171  		t.Run(tc.name, func(t *testing.T) {
   172  			t.Parallel()
   173  
   174  			// Ensure tests don't conflict on the same directory
   175  			tmpDir := t.TempDir()
   176  			require.NoError(t, fstest.WriteTestFiles(tmpDir))
   177  
   178  			testOpen_Read(t, &ReadFS{FS: tc.fs(tmpDir)}, tc.expectFileIno, tc.expectDirIno)
   179  		})
   180  	}
   181  }
   182  
   183  func TestReadFS_Stat(t *testing.T) {
   184  	tmpDir := t.TempDir()
   185  	require.NoError(t, fstest.WriteTestFiles(tmpDir))
   186  
   187  	writeable := DirFS(tmpDir)
   188  	testFS := &ReadFS{FS: writeable}
   189  	testStat(t, testFS)
   190  }
   191  
   192  func TestReadFS_Readlink(t *testing.T) {
   193  	tmpDir := t.TempDir()
   194  	require.NoError(t, fstest.WriteTestFiles(tmpDir))
   195  
   196  	writeable := DirFS(tmpDir)
   197  	testFS := &ReadFS{FS: writeable}
   198  	testReadlink(t, testFS, writeable)
   199  }