github.com/10XDev/rclone@v1.52.3-0.20200626220027-16af9ab76b2a/backend/cache/cache_upload_test.go (about) 1 // +build !plan9 2 // +build !race 3 4 package cache_test 5 6 import ( 7 "context" 8 "fmt" 9 "math/rand" 10 "os" 11 "path" 12 "strconv" 13 "testing" 14 "time" 15 16 "github.com/rclone/rclone/backend/cache" 17 _ "github.com/rclone/rclone/backend/drive" 18 "github.com/rclone/rclone/fs" 19 "github.com/stretchr/testify/require" 20 ) 21 22 func TestInternalUploadTempDirCreated(t *testing.T) { 23 id := fmt.Sprintf("tiutdc%v", time.Now().Unix()) 24 rootFs, boltDb := runInstance.newCacheFs(t, remoteName, id, false, true, 25 nil, 26 map[string]string{"tmp_upload_path": path.Join(runInstance.tmpUploadDir, id)}) 27 defer runInstance.cleanupFs(t, rootFs, boltDb) 28 29 _, err := os.Stat(path.Join(runInstance.tmpUploadDir, id)) 30 require.NoError(t, err) 31 } 32 33 func testInternalUploadQueueOneFile(t *testing.T, id string, rootFs fs.Fs, boltDb *cache.Persistent) { 34 // create some rand test data 35 testSize := int64(524288000) 36 testReader := runInstance.randomReader(t, testSize) 37 bu := runInstance.listenForBackgroundUpload(t, rootFs, "one") 38 runInstance.writeRemoteReader(t, rootFs, "one", testReader) 39 // validate that it exists in temp fs 40 ti, err := os.Stat(path.Join(runInstance.tmpUploadDir, id, runInstance.encryptRemoteIfNeeded(t, "one"))) 41 require.NoError(t, err) 42 43 if runInstance.rootIsCrypt { 44 require.Equal(t, int64(524416032), ti.Size()) 45 } else { 46 require.Equal(t, testSize, ti.Size()) 47 } 48 de1, err := runInstance.list(t, rootFs, "") 49 require.NoError(t, err) 50 require.Len(t, de1, 1) 51 52 runInstance.completeBackgroundUpload(t, "one", bu) 53 // check if it was removed from temp fs 54 _, err = os.Stat(path.Join(runInstance.tmpUploadDir, id, runInstance.encryptRemoteIfNeeded(t, "one"))) 55 require.True(t, os.IsNotExist(err)) 56 57 // check if it can be read 58 data2, err := runInstance.readDataFromRemote(t, rootFs, "one", 0, int64(1024), false) 59 require.NoError(t, err) 60 require.Len(t, data2, 1024) 61 } 62 63 func TestInternalUploadQueueOneFileNoRest(t *testing.T) { 64 id := fmt.Sprintf("tiuqofnr%v", time.Now().Unix()) 65 rootFs, boltDb := runInstance.newCacheFs(t, remoteName, id, true, true, 66 nil, 67 map[string]string{"tmp_upload_path": path.Join(runInstance.tmpUploadDir, id), "tmp_wait_time": "0s"}) 68 defer runInstance.cleanupFs(t, rootFs, boltDb) 69 70 testInternalUploadQueueOneFile(t, id, rootFs, boltDb) 71 } 72 73 func TestInternalUploadQueueOneFileWithRest(t *testing.T) { 74 id := fmt.Sprintf("tiuqofwr%v", time.Now().Unix()) 75 rootFs, boltDb := runInstance.newCacheFs(t, remoteName, id, true, true, 76 nil, 77 map[string]string{"tmp_upload_path": path.Join(runInstance.tmpUploadDir, id), "tmp_wait_time": "1m"}) 78 defer runInstance.cleanupFs(t, rootFs, boltDb) 79 80 testInternalUploadQueueOneFile(t, id, rootFs, boltDb) 81 } 82 83 func TestInternalUploadMoveExistingFile(t *testing.T) { 84 id := fmt.Sprintf("tiumef%v", time.Now().Unix()) 85 rootFs, boltDb := runInstance.newCacheFs(t, remoteName, id, true, true, 86 nil, 87 map[string]string{"tmp_upload_path": path.Join(runInstance.tmpUploadDir, id), "tmp_wait_time": "3s"}) 88 defer runInstance.cleanupFs(t, rootFs, boltDb) 89 90 err := rootFs.Mkdir(context.Background(), "one") 91 require.NoError(t, err) 92 err = rootFs.Mkdir(context.Background(), "one/test") 93 require.NoError(t, err) 94 err = rootFs.Mkdir(context.Background(), "second") 95 require.NoError(t, err) 96 97 // create some rand test data 98 testSize := int64(10485760) 99 testReader := runInstance.randomReader(t, testSize) 100 runInstance.writeObjectReader(t, rootFs, "one/test/data.bin", testReader) 101 runInstance.completeAllBackgroundUploads(t, rootFs, "one/test/data.bin") 102 103 de1, err := runInstance.list(t, rootFs, "one/test") 104 require.NoError(t, err) 105 require.Len(t, de1, 1) 106 107 time.Sleep(time.Second * 5) 108 //_ = os.Remove(path.Join(runInstance.tmpUploadDir, id, runInstance.encryptRemoteIfNeeded(t, "one/test"))) 109 //require.NoError(t, err) 110 111 err = runInstance.dirMove(t, rootFs, "one/test", "second/test") 112 require.NoError(t, err) 113 114 // check if it can be read 115 de1, err = runInstance.list(t, rootFs, "second/test") 116 require.NoError(t, err) 117 require.Len(t, de1, 1) 118 } 119 120 func TestInternalUploadTempPathCleaned(t *testing.T) { 121 id := fmt.Sprintf("tiutpc%v", time.Now().Unix()) 122 rootFs, boltDb := runInstance.newCacheFs(t, remoteName, id, true, true, 123 nil, 124 map[string]string{"cache-tmp-upload-path": path.Join(runInstance.tmpUploadDir, id), "cache-tmp-wait-time": "5s"}) 125 defer runInstance.cleanupFs(t, rootFs, boltDb) 126 127 err := rootFs.Mkdir(context.Background(), "one") 128 require.NoError(t, err) 129 err = rootFs.Mkdir(context.Background(), "one/test") 130 require.NoError(t, err) 131 err = rootFs.Mkdir(context.Background(), "second") 132 require.NoError(t, err) 133 134 // create some rand test data 135 testSize := int64(1048576) 136 testReader := runInstance.randomReader(t, testSize) 137 testReader2 := runInstance.randomReader(t, testSize) 138 runInstance.writeObjectReader(t, rootFs, "one/test/data.bin", testReader) 139 runInstance.writeObjectReader(t, rootFs, "second/data.bin", testReader2) 140 141 runInstance.completeAllBackgroundUploads(t, rootFs, "one/test/data.bin") 142 _, err = os.Stat(path.Join(runInstance.tmpUploadDir, id, runInstance.encryptRemoteIfNeeded(t, "one/test"))) 143 require.True(t, os.IsNotExist(err)) 144 _, err = os.Stat(path.Join(runInstance.tmpUploadDir, id, runInstance.encryptRemoteIfNeeded(t, "one"))) 145 require.True(t, os.IsNotExist(err)) 146 _, err = os.Stat(path.Join(runInstance.tmpUploadDir, id, runInstance.encryptRemoteIfNeeded(t, "second"))) 147 require.False(t, os.IsNotExist(err)) 148 149 runInstance.completeAllBackgroundUploads(t, rootFs, "second/data.bin") 150 _, err = os.Stat(path.Join(runInstance.tmpUploadDir, id, runInstance.encryptRemoteIfNeeded(t, "second/data.bin"))) 151 require.True(t, os.IsNotExist(err)) 152 153 de1, err := runInstance.list(t, rootFs, "one/test") 154 require.NoError(t, err) 155 require.Len(t, de1, 1) 156 157 // check if it can be read 158 de1, err = runInstance.list(t, rootFs, "second") 159 require.NoError(t, err) 160 require.Len(t, de1, 1) 161 } 162 163 func TestInternalUploadQueueMoreFiles(t *testing.T) { 164 id := fmt.Sprintf("tiuqmf%v", time.Now().Unix()) 165 rootFs, boltDb := runInstance.newCacheFs(t, remoteName, id, true, true, 166 nil, 167 map[string]string{"tmp_upload_path": path.Join(runInstance.tmpUploadDir, id), "tmp_wait_time": "1s"}) 168 defer runInstance.cleanupFs(t, rootFs, boltDb) 169 170 err := rootFs.Mkdir(context.Background(), "test") 171 require.NoError(t, err) 172 minSize := 5242880 173 maxSize := 10485760 174 totalFiles := 10 175 rand.Seed(time.Now().Unix()) 176 177 lastFile := "" 178 for i := 0; i < totalFiles; i++ { 179 size := int64(rand.Intn(maxSize-minSize) + minSize) 180 testReader := runInstance.randomReader(t, size) 181 remote := "test/" + strconv.Itoa(i) + ".bin" 182 runInstance.writeRemoteReader(t, rootFs, remote, testReader) 183 184 // validate that it exists in temp fs 185 ti, err := os.Stat(path.Join(runInstance.tmpUploadDir, id, runInstance.encryptRemoteIfNeeded(t, remote))) 186 require.NoError(t, err) 187 require.Equal(t, size, runInstance.cleanSize(t, ti.Size())) 188 189 if runInstance.wrappedIsExternal && i < totalFiles-1 { 190 time.Sleep(time.Second * 3) 191 } 192 lastFile = remote 193 } 194 195 // check if cache lists all files, likely temp upload didn't finish yet 196 de1, err := runInstance.list(t, rootFs, "test") 197 require.NoError(t, err) 198 require.Len(t, de1, totalFiles) 199 200 // wait for background uploader to do its thing 201 runInstance.completeAllBackgroundUploads(t, rootFs, lastFile) 202 203 // retry until we have no more temp files and fail if they don't go down to 0 204 _, err = os.Stat(path.Join(runInstance.tmpUploadDir, id, runInstance.encryptRemoteIfNeeded(t, "test"))) 205 require.True(t, os.IsNotExist(err)) 206 207 // check if cache lists all files 208 de1, err = runInstance.list(t, rootFs, "test") 209 require.NoError(t, err) 210 require.Len(t, de1, totalFiles) 211 } 212 213 func TestInternalUploadTempFileOperations(t *testing.T) { 214 id := "tiutfo" 215 rootFs, boltDb := runInstance.newCacheFs(t, remoteName, id, true, true, 216 nil, 217 map[string]string{"tmp_upload_path": path.Join(runInstance.tmpUploadDir, id), "tmp_wait_time": "1h"}) 218 defer runInstance.cleanupFs(t, rootFs, boltDb) 219 220 boltDb.PurgeTempUploads() 221 222 // create some rand test data 223 runInstance.mkdir(t, rootFs, "test") 224 runInstance.writeRemoteString(t, rootFs, "test/one", "one content") 225 226 // check if it can be read 227 data1, err := runInstance.readDataFromRemote(t, rootFs, "test/one", 0, int64(len([]byte("one content"))), false) 228 require.NoError(t, err) 229 require.Equal(t, []byte("one content"), data1) 230 // validate that it exists in temp fs 231 _, err = os.Stat(path.Join(runInstance.tmpUploadDir, id, runInstance.encryptRemoteIfNeeded(t, "test/one"))) 232 require.NoError(t, err) 233 234 // test DirMove - allowed 235 err = runInstance.dirMove(t, rootFs, "test", "second") 236 if err != errNotSupported { 237 require.NoError(t, err) 238 _, err = rootFs.NewObject(context.Background(), "test/one") 239 require.Error(t, err) 240 _, err = rootFs.NewObject(context.Background(), "second/one") 241 require.NoError(t, err) 242 // validate that it exists in temp fs 243 _, err = os.Stat(path.Join(runInstance.tmpUploadDir, id, runInstance.encryptRemoteIfNeeded(t, "test/one"))) 244 require.Error(t, err) 245 _, err = os.Stat(path.Join(runInstance.tmpUploadDir, id, runInstance.encryptRemoteIfNeeded(t, "second/one"))) 246 require.NoError(t, err) 247 _, err = boltDb.SearchPendingUpload(runInstance.encryptRemoteIfNeeded(t, path.Join(id, "test/one"))) 248 require.Error(t, err) 249 var started bool 250 started, err = boltDb.SearchPendingUpload(runInstance.encryptRemoteIfNeeded(t, path.Join(id, "second/one"))) 251 require.NoError(t, err) 252 require.False(t, started) 253 runInstance.mkdir(t, rootFs, "test") 254 runInstance.writeRemoteString(t, rootFs, "test/one", "one content") 255 } 256 257 // test Rmdir - allowed 258 err = runInstance.rm(t, rootFs, "test") 259 require.Error(t, err) 260 require.Contains(t, err.Error(), "directory not empty") 261 _, err = rootFs.NewObject(context.Background(), "test/one") 262 require.NoError(t, err) 263 // validate that it exists in temp fs 264 _, err = os.Stat(path.Join(runInstance.tmpUploadDir, id, runInstance.encryptRemoteIfNeeded(t, "test/one"))) 265 require.NoError(t, err) 266 started, err := boltDb.SearchPendingUpload(runInstance.encryptRemoteIfNeeded(t, path.Join(id, "test/one"))) 267 require.False(t, started) 268 require.NoError(t, err) 269 270 // test Move/Rename -- allowed 271 err = runInstance.move(t, rootFs, path.Join("test", "one"), path.Join("test", "second")) 272 if err != errNotSupported { 273 require.NoError(t, err) 274 // try to read from it 275 _, err = rootFs.NewObject(context.Background(), "test/one") 276 require.Error(t, err) 277 _, err = rootFs.NewObject(context.Background(), "test/second") 278 require.NoError(t, err) 279 data2, err := runInstance.readDataFromRemote(t, rootFs, "test/second", 0, int64(len([]byte("one content"))), false) 280 require.NoError(t, err) 281 require.Equal(t, []byte("one content"), data2) 282 // validate that it exists in temp fs 283 _, err = os.Stat(path.Join(runInstance.tmpUploadDir, id, runInstance.encryptRemoteIfNeeded(t, "test/one"))) 284 require.Error(t, err) 285 _, err = os.Stat(path.Join(runInstance.tmpUploadDir, id, runInstance.encryptRemoteIfNeeded(t, "test/second"))) 286 require.NoError(t, err) 287 runInstance.writeRemoteString(t, rootFs, "test/one", "one content") 288 } 289 290 // test Copy -- allowed 291 err = runInstance.copy(t, rootFs, path.Join("test", "one"), path.Join("test", "third")) 292 if err != errNotSupported { 293 require.NoError(t, err) 294 _, err = rootFs.NewObject(context.Background(), "test/one") 295 require.NoError(t, err) 296 _, err = rootFs.NewObject(context.Background(), "test/third") 297 require.NoError(t, err) 298 data2, err := runInstance.readDataFromRemote(t, rootFs, "test/third", 0, int64(len([]byte("one content"))), false) 299 require.NoError(t, err) 300 require.Equal(t, []byte("one content"), data2) 301 // validate that it exists in temp fs 302 _, err = os.Stat(path.Join(runInstance.tmpUploadDir, id, runInstance.encryptRemoteIfNeeded(t, "test/one"))) 303 require.NoError(t, err) 304 _, err = os.Stat(path.Join(runInstance.tmpUploadDir, id, runInstance.encryptRemoteIfNeeded(t, "test/third"))) 305 require.NoError(t, err) 306 } 307 308 // test Remove -- allowed 309 err = runInstance.rm(t, rootFs, "test/one") 310 require.NoError(t, err) 311 _, err = rootFs.NewObject(context.Background(), "test/one") 312 require.Error(t, err) 313 // validate that it doesn't exist in temp fs 314 _, err = os.Stat(path.Join(runInstance.tmpUploadDir, id, runInstance.encryptRemoteIfNeeded(t, "test/one"))) 315 require.Error(t, err) 316 runInstance.writeRemoteString(t, rootFs, "test/one", "one content") 317 318 // test Update -- allowed 319 firstModTime, err := runInstance.modTime(t, rootFs, "test/one") 320 require.NoError(t, err) 321 err = runInstance.updateData(t, rootFs, "test/one", "one content", " updated") 322 require.NoError(t, err) 323 obj2, err := rootFs.NewObject(context.Background(), "test/one") 324 require.NoError(t, err) 325 data2 := runInstance.readDataFromObj(t, obj2, 0, int64(len("one content updated")), false) 326 require.Equal(t, "one content updated", string(data2)) 327 tmpInfo, err := os.Stat(path.Join(runInstance.tmpUploadDir, id, runInstance.encryptRemoteIfNeeded(t, "test/one"))) 328 require.NoError(t, err) 329 if runInstance.rootIsCrypt { 330 require.Equal(t, int64(67), tmpInfo.Size()) 331 } else { 332 require.Equal(t, int64(len(data2)), tmpInfo.Size()) 333 } 334 335 // test SetModTime -- allowed 336 secondModTime, err := runInstance.modTime(t, rootFs, "test/one") 337 require.NoError(t, err) 338 require.NotEqual(t, secondModTime, firstModTime) 339 require.NotEqual(t, time.Time{}, firstModTime) 340 require.NotEqual(t, time.Time{}, secondModTime) 341 } 342 343 func TestInternalUploadUploadingFileOperations(t *testing.T) { 344 id := "tiuufo" 345 rootFs, boltDb := runInstance.newCacheFs(t, remoteName, id, true, true, 346 nil, 347 map[string]string{"tmp_upload_path": path.Join(runInstance.tmpUploadDir, id), "tmp_wait_time": "1h"}) 348 defer runInstance.cleanupFs(t, rootFs, boltDb) 349 350 boltDb.PurgeTempUploads() 351 352 // create some rand test data 353 runInstance.mkdir(t, rootFs, "test") 354 runInstance.writeRemoteString(t, rootFs, "test/one", "one content") 355 356 // check if it can be read 357 data1, err := runInstance.readDataFromRemote(t, rootFs, "test/one", 0, int64(len([]byte("one content"))), false) 358 require.NoError(t, err) 359 require.Equal(t, []byte("one content"), data1) 360 // validate that it exists in temp fs 361 _, err = os.Stat(path.Join(runInstance.tmpUploadDir, id, runInstance.encryptRemoteIfNeeded(t, "test/one"))) 362 require.NoError(t, err) 363 364 err = boltDb.SetPendingUploadToStarted(runInstance.encryptRemoteIfNeeded(t, path.Join(rootFs.Root(), "test/one"))) 365 require.NoError(t, err) 366 367 // test DirMove 368 err = runInstance.dirMove(t, rootFs, "test", "second") 369 if err != errNotSupported { 370 require.Error(t, err) 371 _, err = rootFs.NewObject(context.Background(), "test/one") 372 require.NoError(t, err) 373 // validate that it exists in temp fs 374 _, err = os.Stat(path.Join(runInstance.tmpUploadDir, id, runInstance.encryptRemoteIfNeeded(t, "test/one"))) 375 require.NoError(t, err) 376 _, err = os.Stat(path.Join(runInstance.tmpUploadDir, id, runInstance.encryptRemoteIfNeeded(t, "second/one"))) 377 require.Error(t, err) 378 } 379 380 // test Rmdir 381 err = runInstance.rm(t, rootFs, "test") 382 require.Error(t, err) 383 _, err = rootFs.NewObject(context.Background(), "test/one") 384 require.NoError(t, err) 385 // validate that it doesn't exist in temp fs 386 _, err = os.Stat(path.Join(runInstance.tmpUploadDir, id, runInstance.encryptRemoteIfNeeded(t, "test/one"))) 387 require.NoError(t, err) 388 389 // test Move/Rename 390 err = runInstance.move(t, rootFs, path.Join("test", "one"), path.Join("test", "second")) 391 if err != errNotSupported { 392 require.Error(t, err) 393 // try to read from it 394 _, err = rootFs.NewObject(context.Background(), "test/one") 395 require.NoError(t, err) 396 _, err = rootFs.NewObject(context.Background(), "test/second") 397 require.Error(t, err) 398 // validate that it exists in temp fs 399 _, err = os.Stat(path.Join(runInstance.tmpUploadDir, id, runInstance.encryptRemoteIfNeeded(t, "test/one"))) 400 require.NoError(t, err) 401 _, err = os.Stat(path.Join(runInstance.tmpUploadDir, id, runInstance.encryptRemoteIfNeeded(t, "test/second"))) 402 require.Error(t, err) 403 } 404 405 // test Copy -- allowed 406 err = runInstance.copy(t, rootFs, path.Join("test", "one"), path.Join("test", "third")) 407 if err != errNotSupported { 408 require.NoError(t, err) 409 _, err = rootFs.NewObject(context.Background(), "test/one") 410 require.NoError(t, err) 411 _, err = rootFs.NewObject(context.Background(), "test/third") 412 require.NoError(t, err) 413 data2, err := runInstance.readDataFromRemote(t, rootFs, "test/third", 0, int64(len([]byte("one content"))), false) 414 require.NoError(t, err) 415 require.Equal(t, []byte("one content"), data2) 416 // validate that it exists in temp fs 417 _, err = os.Stat(path.Join(runInstance.tmpUploadDir, id, runInstance.encryptRemoteIfNeeded(t, "test/one"))) 418 require.NoError(t, err) 419 _, err = os.Stat(path.Join(runInstance.tmpUploadDir, id, runInstance.encryptRemoteIfNeeded(t, "test/third"))) 420 require.NoError(t, err) 421 } 422 423 // test Remove 424 err = runInstance.rm(t, rootFs, "test/one") 425 require.Error(t, err) 426 _, err = rootFs.NewObject(context.Background(), "test/one") 427 require.NoError(t, err) 428 // validate that it doesn't exist in temp fs 429 _, err = os.Stat(path.Join(runInstance.tmpUploadDir, id, runInstance.encryptRemoteIfNeeded(t, "test/one"))) 430 require.NoError(t, err) 431 runInstance.writeRemoteString(t, rootFs, "test/one", "one content") 432 433 // test Update - this seems to work. Why? FIXME 434 //firstModTime, err := runInstance.modTime(t, rootFs, "test/one") 435 //require.NoError(t, err) 436 //err = runInstance.updateData(t, rootFs, "test/one", "one content", " updated", func() { 437 // data2 := runInstance.readDataFromRemote(t, rootFs, "test/one", 0, int64(len("one content updated")), true) 438 // require.Equal(t, "one content", string(data2)) 439 // 440 // tmpInfo, err := os.Stat(path.Join(runInstance.tmpUploadDir, id, runInstance.encryptRemoteIfNeeded(t, "test/one"))) 441 // require.NoError(t, err) 442 // if runInstance.rootIsCrypt { 443 // require.Equal(t, int64(67), tmpInfo.Size()) 444 // } else { 445 // require.Equal(t, int64(len(data2)), tmpInfo.Size()) 446 // } 447 //}) 448 //require.Error(t, err) 449 450 // test SetModTime -- seems to work cause of previous 451 //secondModTime, err := runInstance.modTime(t, rootFs, "test/one") 452 //require.NoError(t, err) 453 //require.Equal(t, secondModTime, firstModTime) 454 //require.NotEqual(t, time.Time{}, firstModTime) 455 //require.NotEqual(t, time.Time{}, secondModTime) 456 }