github.com/10XDev/rclone@v1.52.3-0.20200626220027-16af9ab76b2a/vfs/vfs_test.go (about) 1 // Test suite for vfs 2 3 package vfs 4 5 import ( 6 "context" 7 "fmt" 8 "io" 9 "os" 10 "testing" 11 12 "github.com/pkg/errors" 13 _ "github.com/rclone/rclone/backend/all" // import all the backends 14 "github.com/rclone/rclone/fs" 15 "github.com/rclone/rclone/fstest" 16 "github.com/rclone/rclone/vfs/vfscommon" 17 "github.com/stretchr/testify/assert" 18 "github.com/stretchr/testify/require" 19 ) 20 21 // Some times used in the tests 22 var ( 23 t1 = fstest.Time("2001-02-03T04:05:06.499999999Z") 24 t2 = fstest.Time("2011-12-25T12:59:59.123456789Z") 25 t3 = fstest.Time("2011-12-30T12:59:59.000000000Z") 26 ) 27 28 // TestMain drives the tests 29 func TestMain(m *testing.M) { 30 fstest.TestMain(m) 31 } 32 33 // Check baseHandle performs as advertised 34 func TestVFSbaseHandle(t *testing.T) { 35 fh := baseHandle{} 36 37 err := fh.Chdir() 38 assert.Equal(t, ENOSYS, err) 39 40 err = fh.Chmod(0) 41 assert.Equal(t, ENOSYS, err) 42 43 err = fh.Chown(0, 0) 44 assert.Equal(t, ENOSYS, err) 45 46 err = fh.Close() 47 assert.Equal(t, ENOSYS, err) 48 49 fd := fh.Fd() 50 assert.Equal(t, uintptr(0), fd) 51 52 name := fh.Name() 53 assert.Equal(t, "", name) 54 55 _, err = fh.Read(nil) 56 assert.Equal(t, ENOSYS, err) 57 58 _, err = fh.ReadAt(nil, 0) 59 assert.Equal(t, ENOSYS, err) 60 61 _, err = fh.Readdir(0) 62 assert.Equal(t, ENOSYS, err) 63 64 _, err = fh.Readdirnames(0) 65 assert.Equal(t, ENOSYS, err) 66 67 _, err = fh.Seek(0, io.SeekStart) 68 assert.Equal(t, ENOSYS, err) 69 70 _, err = fh.Stat() 71 assert.Equal(t, ENOSYS, err) 72 73 err = fh.Sync() 74 assert.Equal(t, nil, err) 75 76 err = fh.Truncate(0) 77 assert.Equal(t, ENOSYS, err) 78 79 _, err = fh.Write(nil) 80 assert.Equal(t, ENOSYS, err) 81 82 _, err = fh.WriteAt(nil, 0) 83 assert.Equal(t, ENOSYS, err) 84 85 _, err = fh.WriteString("") 86 assert.Equal(t, ENOSYS, err) 87 88 err = fh.Flush() 89 assert.Equal(t, ENOSYS, err) 90 91 err = fh.Release() 92 assert.Equal(t, ENOSYS, err) 93 94 node := fh.Node() 95 assert.Nil(t, node) 96 } 97 98 // TestNew sees if the New command works properly 99 func TestVFSNew(t *testing.T) { 100 r := fstest.NewRun(t) 101 defer r.Finalise() 102 103 // Check making a VFS with nil options 104 vfs := New(r.Fremote, nil) 105 var defaultOpt = vfscommon.DefaultOpt 106 defaultOpt.DirPerms |= os.ModeDir 107 assert.Equal(t, vfs.Opt, defaultOpt) 108 assert.Equal(t, vfs.f, r.Fremote) 109 110 // Check the initialisation 111 var opt = vfscommon.DefaultOpt 112 opt.DirPerms = 0777 113 opt.FilePerms = 0666 114 opt.Umask = 0002 115 vfs = New(r.Fremote, &opt) 116 assert.Equal(t, os.FileMode(0775)|os.ModeDir, vfs.Opt.DirPerms) 117 assert.Equal(t, os.FileMode(0664), vfs.Opt.FilePerms) 118 } 119 120 // TestRoot checks root directory is present and correct 121 func TestVFSRoot(t *testing.T) { 122 r := fstest.NewRun(t) 123 defer r.Finalise() 124 vfs := New(r.Fremote, nil) 125 126 root, err := vfs.Root() 127 require.NoError(t, err) 128 assert.Equal(t, vfs.root, root) 129 assert.True(t, root.IsDir()) 130 assert.Equal(t, vfs.Opt.DirPerms.Perm(), root.Mode().Perm()) 131 } 132 133 func TestVFSStat(t *testing.T) { 134 r := fstest.NewRun(t) 135 defer r.Finalise() 136 vfs := New(r.Fremote, nil) 137 138 file1 := r.WriteObject(context.Background(), "file1", "file1 contents", t1) 139 file2 := r.WriteObject(context.Background(), "dir/file2", "file2 contents", t2) 140 fstest.CheckItems(t, r.Fremote, file1, file2) 141 142 node, err := vfs.Stat("file1") 143 require.NoError(t, err) 144 assert.True(t, node.IsFile()) 145 assert.Equal(t, "file1", node.Name()) 146 147 node, err = vfs.Stat("dir") 148 require.NoError(t, err) 149 assert.True(t, node.IsDir()) 150 assert.Equal(t, "dir", node.Name()) 151 152 node, err = vfs.Stat("dir/file2") 153 require.NoError(t, err) 154 assert.True(t, node.IsFile()) 155 assert.Equal(t, "file2", node.Name()) 156 157 _, err = vfs.Stat("not found") 158 assert.Equal(t, os.ErrNotExist, err) 159 160 _, err = vfs.Stat("dir/not found") 161 assert.Equal(t, os.ErrNotExist, err) 162 163 _, err = vfs.Stat("not found/not found") 164 assert.Equal(t, os.ErrNotExist, err) 165 166 _, err = vfs.Stat("file1/under a file") 167 assert.Equal(t, os.ErrNotExist, err) 168 } 169 170 func TestVFSStatParent(t *testing.T) { 171 r := fstest.NewRun(t) 172 defer r.Finalise() 173 vfs := New(r.Fremote, nil) 174 175 file1 := r.WriteObject(context.Background(), "file1", "file1 contents", t1) 176 file2 := r.WriteObject(context.Background(), "dir/file2", "file2 contents", t2) 177 fstest.CheckItems(t, r.Fremote, file1, file2) 178 179 node, leaf, err := vfs.StatParent("file1") 180 require.NoError(t, err) 181 assert.True(t, node.IsDir()) 182 assert.Equal(t, "/", node.Name()) 183 assert.Equal(t, "file1", leaf) 184 185 node, leaf, err = vfs.StatParent("dir/file2") 186 require.NoError(t, err) 187 assert.True(t, node.IsDir()) 188 assert.Equal(t, "dir", node.Name()) 189 assert.Equal(t, "file2", leaf) 190 191 node, leaf, err = vfs.StatParent("not found") 192 require.NoError(t, err) 193 assert.True(t, node.IsDir()) 194 assert.Equal(t, "/", node.Name()) 195 assert.Equal(t, "not found", leaf) 196 197 _, _, err = vfs.StatParent("not found dir/not found") 198 assert.Equal(t, os.ErrNotExist, err) 199 200 _, _, err = vfs.StatParent("file1/under a file") 201 assert.Equal(t, os.ErrExist, err) 202 } 203 204 func TestVFSOpenFile(t *testing.T) { 205 r := fstest.NewRun(t) 206 defer r.Finalise() 207 vfs := New(r.Fremote, nil) 208 209 file1 := r.WriteObject(context.Background(), "file1", "file1 contents", t1) 210 file2 := r.WriteObject(context.Background(), "dir/file2", "file2 contents", t2) 211 fstest.CheckItems(t, r.Fremote, file1, file2) 212 213 fd, err := vfs.OpenFile("file1", os.O_RDONLY, 0777) 214 require.NoError(t, err) 215 assert.NotNil(t, fd) 216 require.NoError(t, fd.Close()) 217 218 fd, err = vfs.OpenFile("dir", os.O_RDONLY, 0777) 219 require.NoError(t, err) 220 assert.NotNil(t, fd) 221 require.NoError(t, fd.Close()) 222 223 fd, err = vfs.OpenFile("dir/new_file.txt", os.O_RDONLY, 0777) 224 assert.Equal(t, os.ErrNotExist, err) 225 assert.Nil(t, fd) 226 227 fd, err = vfs.OpenFile("dir/new_file.txt", os.O_WRONLY|os.O_CREATE, 0777) 228 require.NoError(t, err) 229 assert.NotNil(t, fd) 230 err = fd.Close() 231 if errors.Cause(err) != fs.ErrorCantUploadEmptyFiles { 232 require.NoError(t, err) 233 } 234 235 fd, err = vfs.OpenFile("not found/new_file.txt", os.O_WRONLY|os.O_CREATE, 0777) 236 assert.Equal(t, os.ErrNotExist, err) 237 assert.Nil(t, fd) 238 } 239 240 func TestVFSRename(t *testing.T) { 241 r := fstest.NewRun(t) 242 defer r.Finalise() 243 features := r.Fremote.Features() 244 if features.Move == nil && features.Copy == nil { 245 return // skip as can't rename files 246 } 247 vfs := New(r.Fremote, nil) 248 249 file1 := r.WriteObject(context.Background(), "dir/file2", "file2 contents", t2) 250 fstest.CheckItems(t, r.Fremote, file1) 251 252 err := vfs.Rename("dir/file2", "dir/file1") 253 require.NoError(t, err) 254 file1.Path = "dir/file1" 255 fstest.CheckItems(t, r.Fremote, file1) 256 257 err = vfs.Rename("dir/file1", "file0") 258 require.NoError(t, err) 259 file1.Path = "file0" 260 fstest.CheckItems(t, r.Fremote, file1) 261 262 err = vfs.Rename("not found/file0", "file0") 263 assert.Equal(t, os.ErrNotExist, err) 264 265 err = vfs.Rename("file0", "not found/file0") 266 assert.Equal(t, os.ErrNotExist, err) 267 } 268 269 func TestVFSStatfs(t *testing.T) { 270 r := fstest.NewRun(t) 271 defer r.Finalise() 272 vfs := New(r.Fremote, nil) 273 274 // pre-conditions 275 assert.Nil(t, vfs.usage) 276 assert.True(t, vfs.usageTime.IsZero()) 277 278 aboutSupported := r.Fremote.Features().About != nil 279 280 // read 281 total, used, free := vfs.Statfs() 282 if !aboutSupported { 283 assert.Equal(t, int64(unknownFreeBytes), total) 284 assert.Equal(t, int64(unknownFreeBytes), free) 285 assert.Equal(t, int64(0), used) 286 return // can't test anything else if About not supported 287 } 288 require.NotNil(t, vfs.usage) 289 assert.False(t, vfs.usageTime.IsZero()) 290 if vfs.usage.Total != nil { 291 assert.Equal(t, *vfs.usage.Total, total) 292 } else { 293 assert.True(t, total >= int64(unknownFreeBytes)) 294 } 295 if vfs.usage.Free != nil { 296 assert.Equal(t, *vfs.usage.Free, free) 297 } else { 298 if vfs.usage.Total != nil && vfs.usage.Used != nil { 299 assert.Equal(t, free, total-used) 300 } else { 301 assert.True(t, free >= int64(unknownFreeBytes)) 302 } 303 } 304 if vfs.usage.Used != nil { 305 assert.Equal(t, *vfs.usage.Used, used) 306 } else { 307 assert.Equal(t, int64(0), used) 308 } 309 310 // read cached 311 oldUsage := vfs.usage 312 oldTime := vfs.usageTime 313 total2, used2, free2 := vfs.Statfs() 314 assert.Equal(t, oldUsage, vfs.usage) 315 assert.Equal(t, total, total2) 316 assert.Equal(t, used, used2) 317 assert.Equal(t, free, free2) 318 assert.Equal(t, oldTime, vfs.usageTime) 319 } 320 321 func TestFillInMissingSizes(t *testing.T) { 322 const unknownFree = 10 323 for _, test := range []struct { 324 total, free, used int64 325 wantTotal, wantUsed, wantFree int64 326 }{ 327 { 328 total: 20, free: 5, used: 15, 329 wantTotal: 20, wantFree: 5, wantUsed: 15, 330 }, 331 { 332 total: 20, free: 5, used: -1, 333 wantTotal: 20, wantFree: 5, wantUsed: 15, 334 }, 335 { 336 total: 20, free: -1, used: 15, 337 wantTotal: 20, wantFree: 5, wantUsed: 15, 338 }, 339 { 340 total: 20, free: -1, used: -1, 341 wantTotal: 20, wantFree: 20, wantUsed: 0, 342 }, 343 { 344 total: -1, free: 5, used: 15, 345 wantTotal: 20, wantFree: 5, wantUsed: 15, 346 }, 347 { 348 total: -1, free: 15, used: -1, 349 wantTotal: 15, wantFree: 15, wantUsed: 0, 350 }, 351 { 352 total: -1, free: -1, used: 15, 353 wantTotal: 25, wantFree: 10, wantUsed: 15, 354 }, 355 { 356 total: -1, free: -1, used: -1, 357 wantTotal: 10, wantFree: 10, wantUsed: 0, 358 }, 359 } { 360 t.Run(fmt.Sprintf("total=%d,free=%d,used=%d", test.total, test.free, test.used), func(t *testing.T) { 361 gotTotal, gotUsed, gotFree := fillInMissingSizes(test.total, test.used, test.free, unknownFree) 362 assert.Equal(t, test.wantTotal, gotTotal, "total") 363 assert.Equal(t, test.wantUsed, gotUsed, "used") 364 assert.Equal(t, test.wantFree, gotFree, "free") 365 }) 366 } 367 }