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

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