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

     1  package sysfs
     2  
     3  import (
     4  	"os"
     5  	"path"
     6  	"testing"
     7  
     8  	"github.com/bananabytelabs/wazero/experimental/sys"
     9  	"github.com/bananabytelabs/wazero/internal/testing/require"
    10  )
    11  
    12  func TestRename(t *testing.T) {
    13  	t.Run("from doesn't exist", func(t *testing.T) {
    14  		tmpDir := t.TempDir()
    15  
    16  		file1Path := path.Join(tmpDir, "file1")
    17  		err := os.WriteFile(file1Path, []byte{1}, 0o600)
    18  		require.NoError(t, err)
    19  
    20  		err = rename(path.Join(tmpDir, "non-exist"), file1Path)
    21  		require.EqualErrno(t, sys.ENOENT, err)
    22  	})
    23  	t.Run("file to non-exist", func(t *testing.T) {
    24  		tmpDir := t.TempDir()
    25  
    26  		file1Path := path.Join(tmpDir, "file1")
    27  		file1Contents := []byte{1}
    28  		err := os.WriteFile(file1Path, file1Contents, 0o600)
    29  		require.NoError(t, err)
    30  
    31  		file2Path := path.Join(tmpDir, "file2")
    32  		errno := rename(file1Path, file2Path)
    33  		require.EqualErrno(t, 0, errno)
    34  
    35  		// Show the prior path no longer exists
    36  		_, err = os.Stat(file1Path)
    37  		require.EqualErrno(t, sys.ENOENT, sys.UnwrapOSError(err))
    38  
    39  		s, err := os.Stat(file2Path)
    40  		require.NoError(t, err)
    41  		require.False(t, s.IsDir())
    42  	})
    43  	t.Run("dir to non-exist", func(t *testing.T) {
    44  		tmpDir := t.TempDir()
    45  
    46  		dir1Path := path.Join(tmpDir, "dir1")
    47  		require.NoError(t, os.Mkdir(dir1Path, 0o700))
    48  
    49  		dir2Path := path.Join(tmpDir, "dir2")
    50  		errno := rename(dir1Path, dir2Path)
    51  		require.EqualErrno(t, 0, errno)
    52  
    53  		// Show the prior path no longer exists
    54  		_, err := os.Stat(dir1Path)
    55  		require.EqualErrno(t, sys.ENOENT, sys.UnwrapOSError(err))
    56  
    57  		s, err := os.Stat(dir2Path)
    58  		require.NoError(t, err)
    59  		require.True(t, s.IsDir())
    60  	})
    61  	t.Run("dir to file", func(t *testing.T) {
    62  		tmpDir := t.TempDir()
    63  
    64  		dir1Path := path.Join(tmpDir, "dir1")
    65  		require.NoError(t, os.Mkdir(dir1Path, 0o700))
    66  
    67  		dir2Path := path.Join(tmpDir, "dir2")
    68  
    69  		// write a file to that path
    70  		err := os.WriteFile(dir2Path, []byte{2}, 0o600)
    71  		require.NoError(t, err)
    72  
    73  		err = rename(dir1Path, dir2Path)
    74  		require.EqualErrno(t, sys.ENOTDIR, err)
    75  	})
    76  	t.Run("file to dir", func(t *testing.T) {
    77  		tmpDir := t.TempDir()
    78  
    79  		file1Path := path.Join(tmpDir, "file1")
    80  		file1Contents := []byte{1}
    81  		err := os.WriteFile(file1Path, file1Contents, 0o600)
    82  		require.NoError(t, err)
    83  
    84  		dir1Path := path.Join(tmpDir, "dir1")
    85  		require.NoError(t, os.Mkdir(dir1Path, 0o700))
    86  
    87  		err = rename(file1Path, dir1Path)
    88  		require.EqualErrno(t, sys.EISDIR, err)
    89  	})
    90  
    91  	// Similar to https://github.com/ziglang/zig/blob/0.10.1/lib/std/fs/test.zig#L567-L582
    92  	t.Run("dir to empty dir should be fine", func(t *testing.T) {
    93  		tmpDir := t.TempDir()
    94  
    95  		dir1 := "dir1"
    96  		dir1Path := path.Join(tmpDir, dir1)
    97  		require.NoError(t, os.Mkdir(dir1Path, 0o700))
    98  
    99  		// add a file to that directory
   100  		file1 := "file1"
   101  		file1Path := path.Join(dir1Path, file1)
   102  		file1Contents := []byte{1}
   103  		err := os.WriteFile(file1Path, file1Contents, 0o600)
   104  		require.NoError(t, err)
   105  
   106  		dir2Path := path.Join(tmpDir, "dir2")
   107  		require.NoError(t, os.Mkdir(dir2Path, 0o700))
   108  
   109  		errno := rename(dir1Path, dir2Path)
   110  		require.EqualErrno(t, 0, errno)
   111  
   112  		// Show the prior path no longer exists
   113  		_, err = os.Stat(dir1Path)
   114  		require.EqualErrno(t, sys.ENOENT, sys.UnwrapOSError(err))
   115  
   116  		// Show the file inside that directory moved
   117  		s, err := os.Stat(path.Join(dir2Path, file1))
   118  		require.NoError(t, err)
   119  		require.False(t, s.IsDir())
   120  	})
   121  
   122  	// Similar to https://github.com/ziglang/zig/blob/0.10.1/lib/std/fs/test.zig#L584-L604
   123  	t.Run("dir to non empty dir should be EXIST", func(t *testing.T) {
   124  		tmpDir := t.TempDir()
   125  
   126  		dir1 := "dir1"
   127  		dir1Path := path.Join(tmpDir, dir1)
   128  		require.NoError(t, os.Mkdir(dir1Path, 0o700))
   129  
   130  		// add a file to that directory
   131  		file1Path := path.Join(dir1Path, "file1")
   132  		file1Contents := []byte{1}
   133  		err := os.WriteFile(file1Path, file1Contents, 0o600)
   134  		require.NoError(t, err)
   135  
   136  		dir2Path := path.Join(tmpDir, "dir2")
   137  		require.NoError(t, os.Mkdir(dir2Path, 0o700))
   138  
   139  		// Make the destination non-empty.
   140  		err = os.WriteFile(path.Join(dir2Path, "existing.txt"), []byte("any thing"), 0o600)
   141  		require.NoError(t, err)
   142  
   143  		err = rename(dir1Path, dir2Path)
   144  		require.EqualErrno(t, sys.ENOTEMPTY, err)
   145  	})
   146  
   147  	t.Run("file to file", func(t *testing.T) {
   148  		tmpDir := t.TempDir()
   149  
   150  		file1Path := path.Join(tmpDir, "file1")
   151  		file1Contents := []byte{1}
   152  		err := os.WriteFile(file1Path, file1Contents, 0o600)
   153  		require.NoError(t, err)
   154  
   155  		file2Path := path.Join(tmpDir, "file2")
   156  		file2Contents := []byte{2}
   157  		err = os.WriteFile(file2Path, file2Contents, 0o600)
   158  		require.NoError(t, err)
   159  
   160  		errno := rename(file1Path, file2Path)
   161  		require.EqualErrno(t, 0, errno)
   162  
   163  		// Show the prior path no longer exists
   164  		_, err = os.Stat(file1Path)
   165  		require.EqualErrno(t, sys.ENOENT, sys.UnwrapOSError(err))
   166  
   167  		// Show the file1 overwrote file2
   168  		b, err := os.ReadFile(file2Path)
   169  		require.NoError(t, err)
   170  		require.Equal(t, file1Contents, b)
   171  	})
   172  	t.Run("dir to itself", func(t *testing.T) {
   173  		tmpDir := t.TempDir()
   174  
   175  		dir1Path := path.Join(tmpDir, "dir1")
   176  		require.NoError(t, os.Mkdir(dir1Path, 0o700))
   177  
   178  		errno := rename(dir1Path, dir1Path)
   179  		require.EqualErrno(t, 0, errno)
   180  
   181  		s, err := os.Stat(dir1Path)
   182  		require.NoError(t, err)
   183  		require.True(t, s.IsDir())
   184  	})
   185  	t.Run("file to itself", func(t *testing.T) {
   186  		tmpDir := t.TempDir()
   187  
   188  		file1Path := path.Join(tmpDir, "file1")
   189  		file1Contents := []byte{1}
   190  		err := os.WriteFile(file1Path, file1Contents, 0o600)
   191  		require.NoError(t, err)
   192  
   193  		errno := rename(file1Path, file1Path)
   194  		require.EqualErrno(t, 0, errno)
   195  
   196  		b, err := os.ReadFile(file1Path)
   197  		require.NoError(t, err)
   198  		require.Equal(t, file1Contents, b)
   199  	})
   200  }