github.com/rclone/rclone@v1.66.1-0.20240517100346-7b89735ae726/lib/file/file_test.go (about) 1 package file 2 3 import ( 4 "fmt" 5 "io" 6 "os" 7 "path" 8 "runtime" 9 "testing" 10 11 "github.com/stretchr/testify/assert" 12 "github.com/stretchr/testify/require" 13 ) 14 15 // This lists dir and checks the listing is as expected without checking the size 16 func checkListingNoSize(t *testing.T, dir string, want []string) { 17 var got []string 18 nodes, err := os.ReadDir(dir) 19 require.NoError(t, err) 20 for _, node := range nodes { 21 got = append(got, fmt.Sprintf("%s,%v", node.Name(), node.IsDir())) 22 } 23 assert.Equal(t, want, got) 24 } 25 26 // This lists dir and checks the listing is as expected 27 func checkListing(t *testing.T, dir string, want []string) { 28 var got []string 29 nodes, err := os.ReadDir(dir) 30 require.NoError(t, err) 31 for _, node := range nodes { 32 info, err := node.Info() 33 assert.NoError(t, err) 34 got = append(got, fmt.Sprintf("%s,%d,%v", node.Name(), info.Size(), node.IsDir())) 35 } 36 assert.Equal(t, want, got) 37 } 38 39 // Test we can rename an open file 40 func TestOpenFileRename(t *testing.T) { 41 dir := t.TempDir() 42 43 filepath := path.Join(dir, "file1") 44 f, err := Create(filepath) 45 require.NoError(t, err) 46 47 _, err = f.Write([]byte("hello")) 48 assert.NoError(t, err) 49 50 checkListingNoSize(t, dir, []string{ 51 "file1,false", 52 }) 53 54 // Delete the file first 55 assert.NoError(t, os.Remove(filepath)) 56 57 // .. then close it 58 assert.NoError(t, f.Close()) 59 60 checkListing(t, dir, nil) 61 } 62 63 // Test we can delete an open file 64 func TestOpenFileDelete(t *testing.T) { 65 dir := t.TempDir() 66 67 filepath := path.Join(dir, "file1") 68 f, err := Create(filepath) 69 require.NoError(t, err) 70 71 _, err = f.Write([]byte("hello")) 72 assert.NoError(t, err) 73 74 checkListingNoSize(t, dir, []string{ 75 "file1,false", 76 }) 77 78 // Rename the file while open 79 filepath2 := path.Join(dir, "file2") 80 assert.NoError(t, os.Rename(filepath, filepath2)) 81 82 checkListingNoSize(t, dir, []string{ 83 "file2,false", 84 }) 85 86 // .. then close it 87 assert.NoError(t, f.Close()) 88 89 checkListing(t, dir, []string{ 90 "file2,5,false", 91 }) 92 } 93 94 // Smoke test the Open, OpenFile and Create functions 95 func TestOpenFileOperations(t *testing.T) { 96 dir := t.TempDir() 97 98 filepath := path.Join(dir, "file1") 99 100 // Create the file 101 102 f, err := Create(filepath) 103 require.NoError(t, err) 104 105 _, err = f.Write([]byte("hello")) 106 assert.NoError(t, err) 107 108 assert.NoError(t, f.Close()) 109 110 checkListing(t, dir, []string{ 111 "file1,5,false", 112 }) 113 114 // Append onto the file 115 116 f, err = OpenFile(filepath, os.O_RDWR|os.O_APPEND, 0666) 117 require.NoError(t, err) 118 119 _, err = f.Write([]byte("HI")) 120 assert.NoError(t, err) 121 122 assert.NoError(t, f.Close()) 123 124 checkListing(t, dir, []string{ 125 "file1,7,false", 126 }) 127 128 // Read it back in 129 130 f, err = Open(filepath) 131 require.NoError(t, err) 132 var b = make([]byte, 10) 133 n, err := f.Read(b) 134 assert.True(t, err == io.EOF || err == nil) 135 assert.Equal(t, 7, n) 136 assert.Equal(t, "helloHI", string(b[:n])) 137 138 assert.NoError(t, f.Close()) 139 140 checkListing(t, dir, []string{ 141 "file1,7,false", 142 }) 143 144 } 145 146 // Smoke test the IsReserved function 147 func TestIsReserved(t *testing.T) { 148 if runtime.GOOS != "windows" { 149 t.Skip("Skipping test on !windows") 150 } 151 // Regular name 152 require.NoError(t, IsReserved("readme.txt")) 153 require.NoError(t, IsReserved("some/path/readme.txt")) 154 // Empty 155 require.Error(t, IsReserved("")) 156 // Separators only 157 require.Error(t, IsReserved("/")) 158 require.Error(t, IsReserved("////")) 159 require.Error(t, IsReserved("./././././")) 160 // Legacy device name 161 require.Error(t, IsReserved("NUL")) 162 require.Error(t, IsReserved("nul")) 163 require.Error(t, IsReserved("Nul")) 164 require.Error(t, IsReserved("NUL.txt")) 165 require.Error(t, IsReserved("some/path/to/nul.txt")) 166 require.NoError(t, IsReserved("NULL")) 167 // Name end with a space or a period 168 require.Error(t, IsReserved("test.")) 169 require.Error(t, IsReserved("test ")) 170 }