github.com/xhghs/rclone@v1.51.1-0.20200430155106-e186a28cced8/vfs/vfs_case_test.go (about) 1 package vfs 2 3 import ( 4 "context" 5 "os" 6 "testing" 7 8 "github.com/rclone/rclone/fstest" 9 "github.com/stretchr/testify/assert" 10 "github.com/stretchr/testify/require" 11 ) 12 13 func TestCaseSensitivity(t *testing.T) { 14 r := fstest.NewRun(t) 15 defer r.Finalise() 16 17 if r.Fremote.Features().CaseInsensitive { 18 t.Skip("Can't test case sensitivity - this remote is officially not case-sensitive") 19 } 20 21 // Create test files 22 ctx := context.Background() 23 file1 := r.WriteObject(ctx, "FiLeA", "data1", t1) 24 file2 := r.WriteObject(ctx, "FiLeB", "data2", t2) 25 fstest.CheckItems(t, r.Fremote, file1, file2) 26 27 // Create file3 with name differing from file2 name only by case. 28 // On a case-Sensitive remote this will be a separate file. 29 // On a case-INsensitive remote this file will either not exist 30 // or overwrite file2 depending on how file system diverges. 31 // On a box.com remote this step will even fail. 32 file3 := r.WriteObject(ctx, "FilEb", "data3", t3) 33 34 // Create a case-Sensitive and case-INsensitive VFS 35 optCS := DefaultOpt 36 optCS.CaseInsensitive = false 37 vfsCS := New(r.Fremote, &optCS) 38 39 optCI := DefaultOpt 40 optCI.CaseInsensitive = true 41 vfsCI := New(r.Fremote, &optCI) 42 43 // Run basic checks that must pass on VFS of any type. 44 assertFileDataVFS(t, vfsCI, "FiLeA", "data1") 45 assertFileDataVFS(t, vfsCS, "FiLeA", "data1") 46 47 // Detect case sensitivity of the underlying remote. 48 remoteIsOK := true 49 if !checkFileDataVFS(t, vfsCS, "FiLeA", "data1") { 50 remoteIsOK = false 51 } 52 if !checkFileDataVFS(t, vfsCS, "FiLeB", "data2") { 53 remoteIsOK = false 54 } 55 if !checkFileDataVFS(t, vfsCS, "FilEb", "data3") { 56 remoteIsOK = false 57 } 58 59 // The remaining test is only meaningful on a case-Sensitive file system. 60 if !remoteIsOK { 61 t.Skip("Can't test case sensitivity - this remote doesn't comply as case-sensitive") 62 } 63 64 // Continue with test as the underlying remote is fully case-Sensitive. 65 fstest.CheckItems(t, r.Fremote, file1, file2, file3) 66 67 // See how VFS handles case-INsensitive flag 68 assertFileDataVFS(t, vfsCI, "FiLeA", "data1") 69 assertFileDataVFS(t, vfsCI, "fileA", "data1") 70 assertFileDataVFS(t, vfsCI, "filea", "data1") 71 assertFileDataVFS(t, vfsCI, "FILEA", "data1") 72 73 assertFileDataVFS(t, vfsCI, "FiLeB", "data2") 74 assertFileDataVFS(t, vfsCI, "FilEb", "data3") 75 76 fd, err := vfsCI.OpenFile("fileb", os.O_RDONLY, 0777) 77 assert.Nil(t, fd) 78 assert.Error(t, err) 79 assert.NotEqual(t, err, ENOENT) 80 81 fd, err = vfsCI.OpenFile("FILEB", os.O_RDONLY, 0777) 82 assert.Nil(t, fd) 83 assert.Error(t, err) 84 assert.NotEqual(t, err, ENOENT) 85 86 // Run the same set of checks with case-Sensitive VFS, for comparison. 87 assertFileDataVFS(t, vfsCS, "FiLeA", "data1") 88 89 assertFileAbsentVFS(t, vfsCS, "fileA") 90 assertFileAbsentVFS(t, vfsCS, "filea") 91 assertFileAbsentVFS(t, vfsCS, "FILEA") 92 93 assertFileDataVFS(t, vfsCS, "FiLeB", "data2") 94 assertFileDataVFS(t, vfsCS, "FilEb", "data3") 95 96 assertFileAbsentVFS(t, vfsCS, "fileb") 97 assertFileAbsentVFS(t, vfsCS, "FILEB") 98 } 99 100 func checkFileDataVFS(t *testing.T, vfs *VFS, name string, expect string) bool { 101 fd, err := vfs.OpenFile(name, os.O_RDONLY, 0777) 102 if fd == nil || err != nil { 103 return false 104 } 105 defer func() { 106 // File must be closed - otherwise Run.cleanUp() will fail on Windows. 107 _ = fd.Close() 108 }() 109 110 fh, ok := fd.(*ReadFileHandle) 111 if !ok { 112 return false 113 } 114 115 size := len(expect) 116 buf := make([]byte, size) 117 num, err := fh.Read(buf) 118 if err != nil || num != size { 119 return false 120 } 121 122 return string(buf) == expect 123 } 124 125 func assertFileDataVFS(t *testing.T, vfs *VFS, name string, expect string) { 126 fd, errOpen := vfs.OpenFile(name, os.O_RDONLY, 0777) 127 assert.NotNil(t, fd) 128 assert.NoError(t, errOpen) 129 130 defer func() { 131 // File must be closed - otherwise Run.cleanUp() will fail on Windows. 132 if errOpen == nil && fd != nil { 133 _ = fd.Close() 134 } 135 }() 136 137 fh, ok := fd.(*ReadFileHandle) 138 require.True(t, ok) 139 140 size := len(expect) 141 buf := make([]byte, size) 142 numRead, errRead := fh.Read(buf) 143 assert.NoError(t, errRead) 144 assert.Equal(t, numRead, size) 145 146 assert.Equal(t, string(buf), expect) 147 } 148 149 func assertFileAbsentVFS(t *testing.T, vfs *VFS, name string) { 150 fd, err := vfs.OpenFile(name, os.O_RDONLY, 0777) 151 defer func() { 152 // File must be closed - otherwise Run.cleanUp() will fail on Windows. 153 if err == nil && fd != nil { 154 _ = fd.Close() 155 } 156 }() 157 assert.Nil(t, fd) 158 assert.Error(t, err) 159 assert.Equal(t, err, ENOENT) 160 }