github.com/10XDev/rclone@v1.52.3-0.20200626220027-16af9ab76b2a/vfs/read_write_test.go (about) 1 package vfs 2 3 import ( 4 "context" 5 "fmt" 6 "io" 7 "io/ioutil" 8 "os" 9 "testing" 10 "time" 11 12 "github.com/pkg/errors" 13 "github.com/rclone/rclone/fs" 14 "github.com/rclone/rclone/fs/operations" 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 func cleanup(t *testing.T, r *fstest.Run, vfs *VFS) { 22 assert.NoError(t, vfs.CleanUp()) 23 vfs.Shutdown() 24 r.Finalise() 25 } 26 27 // Create a file and open it with the flags passed in 28 func rwHandleCreateFlags(t *testing.T, r *fstest.Run, create bool, filename string, flags int) (*VFS, *RWFileHandle) { 29 opt := vfscommon.DefaultOpt 30 opt.CacheMode = vfscommon.CacheModeFull 31 vfs := New(r.Fremote, &opt) 32 33 if create { 34 file1 := r.WriteObject(context.Background(), filename, "0123456789abcdef", t1) 35 fstest.CheckItems(t, r.Fremote, file1) 36 } 37 38 h, err := vfs.OpenFile(filename, flags, 0777) 39 require.NoError(t, err) 40 fh, ok := h.(*RWFileHandle) 41 require.True(t, ok) 42 43 return vfs, fh 44 } 45 46 // Open a file for read 47 func rwHandleCreateReadOnly(t *testing.T, r *fstest.Run) (*VFS, *RWFileHandle) { 48 return rwHandleCreateFlags(t, r, true, "dir/file1", os.O_RDONLY) 49 } 50 51 // Open a file for write 52 func rwHandleCreateWriteOnly(t *testing.T, r *fstest.Run) (*VFS, *RWFileHandle) { 53 return rwHandleCreateFlags(t, r, false, "file1", os.O_WRONLY|os.O_CREATE) 54 } 55 56 // read data from the string 57 func rwReadString(t *testing.T, fh *RWFileHandle, n int) string { 58 buf := make([]byte, n) 59 n, err := fh.Read(buf) 60 if err != io.EOF { 61 assert.NoError(t, err) 62 } 63 return string(buf[:n]) 64 } 65 66 func TestRWFileHandleMethodsRead(t *testing.T) { 67 r := fstest.NewRun(t) 68 vfs, fh := rwHandleCreateReadOnly(t, r) 69 defer cleanup(t, r, vfs) 70 71 // String 72 assert.Equal(t, "dir/file1 (rw)", fh.String()) 73 assert.Equal(t, "<nil *RWFileHandle>", (*RWFileHandle)(nil).String()) 74 assert.Equal(t, "<nil *RWFileHandle.file>", new(RWFileHandle).String()) 75 76 // Node 77 node := fh.Node() 78 assert.Equal(t, "file1", node.Name()) 79 80 // Size 81 assert.Equal(t, int64(16), fh.Size()) 82 83 // No opens yet 84 assert.Equal(t, 0, fh.file.rwOpens()) 85 86 // Read 1 87 assert.Equal(t, "0", rwReadString(t, fh, 1)) 88 89 // Open after the read 90 assert.Equal(t, 1, fh.file.rwOpens()) 91 92 // Read remainder 93 assert.Equal(t, "123456789abcdef", rwReadString(t, fh, 256)) 94 95 // Read EOF 96 buf := make([]byte, 16) 97 _, err := fh.Read(buf) 98 assert.Equal(t, io.EOF, err) 99 100 // Sync 101 err = fh.Sync() 102 assert.NoError(t, err) 103 104 // Stat 105 var fi os.FileInfo 106 fi, err = fh.Stat() 107 assert.NoError(t, err) 108 assert.Equal(t, int64(16), fi.Size()) 109 assert.Equal(t, "file1", fi.Name()) 110 111 // Close 112 assert.False(t, fh.closed) 113 assert.Equal(t, nil, fh.Close()) 114 assert.True(t, fh.closed) 115 116 // No opens again 117 assert.Equal(t, 0, fh.file.rwOpens()) 118 119 // Close again 120 assert.Equal(t, ECLOSED, fh.Close()) 121 } 122 123 func TestRWFileHandleSeek(t *testing.T) { 124 r := fstest.NewRun(t) 125 vfs, fh := rwHandleCreateReadOnly(t, r) 126 defer cleanup(t, r, vfs) 127 128 assert.Equal(t, fh.opened, false) 129 130 // Check null seeks don't open the file 131 n, err := fh.Seek(0, io.SeekStart) 132 assert.NoError(t, err) 133 assert.Equal(t, int64(0), n) 134 assert.Equal(t, fh.opened, false) 135 n, err = fh.Seek(0, io.SeekCurrent) 136 assert.NoError(t, err) 137 assert.Equal(t, int64(0), n) 138 assert.Equal(t, fh.opened, false) 139 140 assert.Equal(t, "0", rwReadString(t, fh, 1)) 141 142 // 0 means relative to the origin of the file, 143 n, err = fh.Seek(5, io.SeekStart) 144 assert.NoError(t, err) 145 assert.Equal(t, int64(5), n) 146 assert.Equal(t, "5", rwReadString(t, fh, 1)) 147 148 // 1 means relative to the current offset 149 n, err = fh.Seek(-3, io.SeekCurrent) 150 assert.NoError(t, err) 151 assert.Equal(t, int64(3), n) 152 assert.Equal(t, "3", rwReadString(t, fh, 1)) 153 154 // 2 means relative to the end. 155 n, err = fh.Seek(-3, io.SeekEnd) 156 assert.NoError(t, err) 157 assert.Equal(t, int64(13), n) 158 assert.Equal(t, "d", rwReadString(t, fh, 1)) 159 160 // Seek off the end 161 _, err = fh.Seek(100, io.SeekStart) 162 assert.NoError(t, err) 163 164 // Get the error on read 165 buf := make([]byte, 16) 166 l, err := fh.Read(buf) 167 assert.Equal(t, io.EOF, err) 168 assert.Equal(t, 0, l) 169 170 // Close 171 assert.Equal(t, nil, fh.Close()) 172 } 173 174 func TestRWFileHandleReadAt(t *testing.T) { 175 r := fstest.NewRun(t) 176 vfs, fh := rwHandleCreateReadOnly(t, r) 177 defer cleanup(t, r, vfs) 178 179 // read from start 180 buf := make([]byte, 1) 181 n, err := fh.ReadAt(buf, 0) 182 require.NoError(t, err) 183 assert.Equal(t, 1, n) 184 assert.Equal(t, "0", string(buf[:n])) 185 186 // seek forwards 187 n, err = fh.ReadAt(buf, 5) 188 require.NoError(t, err) 189 assert.Equal(t, 1, n) 190 assert.Equal(t, "5", string(buf[:n])) 191 192 // seek backwards 193 n, err = fh.ReadAt(buf, 1) 194 require.NoError(t, err) 195 assert.Equal(t, 1, n) 196 assert.Equal(t, "1", string(buf[:n])) 197 198 // read exactly to the end 199 buf = make([]byte, 6) 200 n, err = fh.ReadAt(buf, 10) 201 require.NoError(t, err) 202 assert.Equal(t, 6, n) 203 assert.Equal(t, "abcdef", string(buf[:n])) 204 205 // read off the end 206 buf = make([]byte, 256) 207 n, err = fh.ReadAt(buf, 10) 208 assert.Equal(t, io.EOF, err) 209 assert.Equal(t, 6, n) 210 assert.Equal(t, "abcdef", string(buf[:n])) 211 212 // read starting off the end 213 n, err = fh.ReadAt(buf, 100) 214 assert.Equal(t, io.EOF, err) 215 assert.Equal(t, 0, n) 216 217 // Properly close the file 218 assert.NoError(t, fh.Close()) 219 220 // check reading on closed file 221 _, err = fh.ReadAt(buf, 100) 222 assert.Equal(t, ECLOSED, err) 223 } 224 225 func TestRWFileHandleFlushRead(t *testing.T) { 226 r := fstest.NewRun(t) 227 vfs, fh := rwHandleCreateReadOnly(t, r) 228 defer cleanup(t, r, vfs) 229 230 // Check Flush does nothing if read not called 231 err := fh.Flush() 232 assert.NoError(t, err) 233 assert.False(t, fh.closed) 234 235 // Read data 236 buf := make([]byte, 256) 237 n, err := fh.Read(buf) 238 assert.True(t, err == io.EOF || err == nil) 239 assert.Equal(t, 16, n) 240 241 // Check Flush does nothing if read called 242 err = fh.Flush() 243 assert.NoError(t, err) 244 assert.False(t, fh.closed) 245 246 // Check flush does nothing if called again 247 err = fh.Flush() 248 assert.NoError(t, err) 249 assert.False(t, fh.closed) 250 251 // Properly close the file 252 assert.NoError(t, fh.Close()) 253 } 254 255 func TestRWFileHandleReleaseRead(t *testing.T) { 256 r := fstest.NewRun(t) 257 vfs, fh := rwHandleCreateReadOnly(t, r) 258 defer cleanup(t, r, vfs) 259 260 // Read data 261 buf := make([]byte, 256) 262 n, err := fh.Read(buf) 263 assert.True(t, err == io.EOF || err == nil) 264 assert.Equal(t, 16, n) 265 266 // Check Release closes file 267 err = fh.Release() 268 assert.NoError(t, err) 269 assert.True(t, fh.closed) 270 271 // Check Release does nothing if called again 272 err = fh.Release() 273 assert.NoError(t, err) 274 assert.True(t, fh.closed) 275 } 276 277 /// ------------------------------------------------------------ 278 279 func TestRWFileHandleMethodsWrite(t *testing.T) { 280 r := fstest.NewRun(t) 281 vfs, fh := rwHandleCreateWriteOnly(t, r) 282 defer cleanup(t, r, vfs) 283 284 // 1 opens since we opened with O_CREATE and the file didn't 285 // exist in the cache 286 assert.Equal(t, 1, fh.file.rwOpens()) 287 288 // String 289 assert.Equal(t, "file1 (rw)", fh.String()) 290 assert.Equal(t, "<nil *RWFileHandle>", (*RWFileHandle)(nil).String()) 291 assert.Equal(t, "<nil *RWFileHandle.file>", new(RWFileHandle).String()) 292 293 // Node 294 node := fh.Node() 295 assert.Equal(t, "file1", node.Name()) 296 297 offset := func() int64 { 298 n, err := fh.Seek(0, io.SeekCurrent) 299 require.NoError(t, err) 300 return n 301 } 302 303 // Offset #1 304 assert.Equal(t, int64(0), offset()) 305 assert.Equal(t, int64(0), node.Size()) 306 307 // Size #1 308 assert.Equal(t, int64(0), fh.Size()) 309 310 // Write 311 n, err := fh.Write([]byte("hello")) 312 assert.NoError(t, err) 313 assert.Equal(t, 5, n) 314 315 // Open after the write 316 assert.Equal(t, 1, fh.file.rwOpens()) 317 318 // Offset #2 319 assert.Equal(t, int64(5), offset()) 320 assert.Equal(t, int64(5), node.Size()) 321 322 // Size #2 323 assert.Equal(t, int64(5), fh.Size()) 324 325 // WriteString 326 n, err = fh.WriteString(" world!") 327 assert.NoError(t, err) 328 assert.Equal(t, 7, n) 329 330 // Sync 331 err = fh.Sync() 332 assert.NoError(t, err) 333 334 // Stat 335 var fi os.FileInfo 336 fi, err = fh.Stat() 337 assert.NoError(t, err) 338 assert.Equal(t, int64(12), fi.Size()) 339 assert.Equal(t, "file1", fi.Name()) 340 341 // Truncate 342 err = fh.Truncate(11) 343 assert.NoError(t, err) 344 345 // Close 346 assert.NoError(t, fh.Close()) 347 348 // No opens again 349 assert.Equal(t, 0, fh.file.rwOpens()) 350 351 // Check double close 352 err = fh.Close() 353 assert.Equal(t, ECLOSED, err) 354 355 // check vfs 356 root, err := vfs.Root() 357 require.NoError(t, err) 358 checkListing(t, root, []string{"file1,11,false"}) 359 360 // check the underlying r.Fremote but not the modtime 361 file1 := fstest.NewItem("file1", "hello world", t1) 362 fstest.CheckListingWithPrecision(t, r.Fremote, []fstest.Item{file1}, []string{}, fs.ModTimeNotSupported) 363 } 364 365 func TestRWFileHandleWriteAt(t *testing.T) { 366 r := fstest.NewRun(t) 367 vfs, fh := rwHandleCreateWriteOnly(t, r) 368 defer cleanup(t, r, vfs) 369 370 offset := func() int64 { 371 n, err := fh.Seek(0, io.SeekCurrent) 372 require.NoError(t, err) 373 return n 374 } 375 376 // Preconditions 377 assert.Equal(t, int64(0), offset()) 378 assert.True(t, fh.opened) 379 assert.False(t, fh.writeCalled) 380 assert.True(t, fh.changed) 381 382 // Write the data 383 n, err := fh.WriteAt([]byte("hello**"), 0) 384 assert.NoError(t, err) 385 assert.Equal(t, 7, n) 386 387 // After write 388 assert.Equal(t, int64(0), offset()) 389 assert.True(t, fh.writeCalled) 390 391 // Write more data 392 n, err = fh.WriteAt([]byte(" world"), 5) 393 assert.NoError(t, err) 394 assert.Equal(t, 6, n) 395 396 // Close 397 assert.NoError(t, fh.Close()) 398 399 // Check can't write on closed handle 400 n, err = fh.WriteAt([]byte("hello"), 0) 401 assert.Equal(t, ECLOSED, err) 402 assert.Equal(t, 0, n) 403 404 // check vfs 405 root, err := vfs.Root() 406 require.NoError(t, err) 407 checkListing(t, root, []string{"file1,11,false"}) 408 409 // check the underlying r.Fremote but not the modtime 410 file1 := fstest.NewItem("file1", "hello world", t1) 411 fstest.CheckListingWithPrecision(t, r.Fremote, []fstest.Item{file1}, []string{}, fs.ModTimeNotSupported) 412 } 413 414 func TestRWFileHandleWriteNoWrite(t *testing.T) { 415 r := fstest.NewRun(t) 416 vfs, fh := rwHandleCreateWriteOnly(t, r) 417 defer cleanup(t, r, vfs) 418 419 // Close the file without writing to it 420 err := fh.Close() 421 if errors.Cause(err) == fs.ErrorCantUploadEmptyFiles { 422 t.Logf("skipping test: %v", err) 423 return 424 } 425 assert.NoError(t, err) 426 427 // Create a different file (not in the cache) 428 h, err := vfs.OpenFile("file2", os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0777) 429 require.NoError(t, err) 430 431 // Close it with Flush and Release 432 err = h.Flush() 433 assert.NoError(t, err) 434 err = h.Release() 435 assert.NoError(t, err) 436 437 // check vfs 438 root, err := vfs.Root() 439 require.NoError(t, err) 440 checkListing(t, root, []string{"file1,0,false", "file2,0,false"}) 441 442 // check the underlying r.Fremote but not the modtime 443 file1 := fstest.NewItem("file1", "", t1) 444 file2 := fstest.NewItem("file2", "", t1) 445 fstest.CheckListingWithPrecision(t, r.Fremote, []fstest.Item{file1, file2}, []string{}, fs.ModTimeNotSupported) 446 } 447 448 func TestRWFileHandleFlushWrite(t *testing.T) { 449 r := fstest.NewRun(t) 450 vfs, fh := rwHandleCreateWriteOnly(t, r) 451 defer cleanup(t, r, vfs) 452 453 // Check that the file has been create and is open 454 assert.True(t, fh.opened) 455 456 // Write some data 457 n, err := fh.Write([]byte("hello")) 458 assert.NoError(t, err) 459 assert.Equal(t, 5, n) 460 461 // Check Flush does not close file if write called 462 err = fh.Flush() 463 assert.NoError(t, err) 464 assert.False(t, fh.closed) 465 466 // Check flush does nothing if called again 467 err = fh.Flush() 468 assert.NoError(t, err) 469 assert.False(t, fh.closed) 470 471 // Check that Close closes the file 472 err = fh.Close() 473 assert.NoError(t, err) 474 assert.True(t, fh.closed) 475 } 476 477 func TestRWFileHandleReleaseWrite(t *testing.T) { 478 r := fstest.NewRun(t) 479 vfs, fh := rwHandleCreateWriteOnly(t, r) 480 defer cleanup(t, r, vfs) 481 482 // Write some data 483 n, err := fh.Write([]byte("hello")) 484 assert.NoError(t, err) 485 assert.Equal(t, 5, n) 486 487 // Check Release closes file 488 err = fh.Release() 489 assert.NoError(t, err) 490 assert.True(t, fh.closed) 491 492 // Check Release does nothing if called again 493 err = fh.Release() 494 assert.NoError(t, err) 495 assert.True(t, fh.closed) 496 } 497 498 // check the size of the file through the open file (if not nil) and via stat 499 func assertSize(t *testing.T, vfs *VFS, fh *RWFileHandle, filepath string, size int64) { 500 if fh != nil { 501 assert.Equal(t, size, fh.Size()) 502 } 503 fi, err := vfs.Stat(filepath) 504 require.NoError(t, err) 505 assert.Equal(t, size, fi.Size()) 506 } 507 508 func TestRWFileHandleSizeTruncateExisting(t *testing.T) { 509 r := fstest.NewRun(t) 510 vfs, fh := rwHandleCreateFlags(t, r, true, "dir/file1", os.O_WRONLY|os.O_TRUNC) 511 defer cleanup(t, r, vfs) 512 513 // check initial size after opening 514 assertSize(t, vfs, fh, "dir/file1", 0) 515 516 // write some bytes 517 n, err := fh.Write([]byte("hello")) 518 assert.NoError(t, err) 519 assert.Equal(t, 5, n) 520 521 // check size after writing 522 assertSize(t, vfs, fh, "dir/file1", 5) 523 524 // close 525 assert.NoError(t, fh.Close()) 526 527 // check size after close 528 assertSize(t, vfs, nil, "dir/file1", 5) 529 } 530 531 func TestRWFileHandleSizeCreateExisting(t *testing.T) { 532 r := fstest.NewRun(t) 533 vfs, fh := rwHandleCreateFlags(t, r, true, "dir/file1", os.O_WRONLY|os.O_CREATE) 534 defer cleanup(t, r, vfs) 535 536 // check initial size after opening 537 assertSize(t, vfs, fh, "dir/file1", 16) 538 539 // write some bytes 540 n, err := fh.Write([]byte("hello")) 541 assert.NoError(t, err) 542 assert.Equal(t, 5, n) 543 544 // check size after writing 545 assertSize(t, vfs, fh, "dir/file1", 16) 546 547 // write some more bytes 548 n, err = fh.Write([]byte("helloHELLOhello")) 549 assert.NoError(t, err) 550 assert.Equal(t, 15, n) 551 552 // check size after writing 553 assertSize(t, vfs, fh, "dir/file1", 20) 554 555 // close 556 assert.NoError(t, fh.Close()) 557 558 // check size after close 559 assertSize(t, vfs, nil, "dir/file1", 20) 560 } 561 562 func TestRWFileHandleSizeCreateNew(t *testing.T) { 563 r := fstest.NewRun(t) 564 vfs, fh := rwHandleCreateFlags(t, r, false, "file1", os.O_WRONLY|os.O_CREATE) 565 defer cleanup(t, r, vfs) 566 567 // check initial size after opening 568 assertSize(t, vfs, fh, "file1", 0) 569 570 // write some bytes 571 n, err := fh.Write([]byte("hello")) 572 assert.NoError(t, err) 573 assert.Equal(t, 5, n) 574 575 // check size after writing 576 assertSize(t, vfs, fh, "file1", 5) 577 578 // check size after writing 579 assertSize(t, vfs, fh, "file1", 5) 580 581 // close 582 assert.NoError(t, fh.Close()) 583 584 // check size after close 585 assertSize(t, vfs, nil, "file1", 5) 586 } 587 588 func testRWFileHandleOpenTest(t *testing.T, vfs *VFS, test *openTest) { 589 fileName := "open-test-file" 590 591 // first try with file not existing 592 _, err := vfs.Stat(fileName) 593 require.True(t, os.IsNotExist(err), test.what) 594 595 f, openNonExistentErr := vfs.OpenFile(fileName, test.flags, 0666) 596 597 var readNonExistentErr error 598 var writeNonExistentErr error 599 if openNonExistentErr == nil { 600 // read some bytes 601 buf := []byte{0, 0} 602 _, readNonExistentErr = f.Read(buf) 603 604 // write some bytes 605 _, writeNonExistentErr = f.Write([]byte("hello")) 606 607 // close 608 err = f.Close() 609 require.NoError(t, err, test.what) 610 } 611 612 // write the file 613 f, err = vfs.OpenFile(fileName, os.O_WRONLY|os.O_CREATE, 0777) 614 require.NoError(t, err, test.what) 615 _, err = f.Write([]byte("hello")) 616 require.NoError(t, err, test.what) 617 err = f.Close() 618 require.NoError(t, err, test.what) 619 620 // then open file and try with file existing 621 622 f, openExistingErr := vfs.OpenFile(fileName, test.flags, 0666) 623 var readExistingErr error 624 var writeExistingErr error 625 if openExistingErr == nil { 626 // read some bytes 627 buf := []byte{0, 0} 628 _, readExistingErr = f.Read(buf) 629 630 // write some bytes 631 _, writeExistingErr = f.Write([]byte("HEL")) 632 633 // close 634 err = f.Close() 635 require.NoError(t, err, test.what) 636 } 637 638 // read the file 639 f, err = vfs.OpenFile(fileName, os.O_RDONLY, 0) 640 require.NoError(t, err, test.what) 641 buf, err := ioutil.ReadAll(f) 642 require.NoError(t, err, test.what) 643 err = f.Close() 644 require.NoError(t, err, test.what) 645 contents := string(buf) 646 647 // remove file 648 node, err := vfs.Stat(fileName) 649 require.NoError(t, err, test.what) 650 err = node.Remove() 651 require.NoError(t, err, test.what) 652 653 // check 654 assert.Equal(t, test.openNonExistentErr, openNonExistentErr, "openNonExistentErr: %s: want=%v, got=%v", test.what, test.openNonExistentErr, openNonExistentErr) 655 assert.Equal(t, test.readNonExistentErr, readNonExistentErr, "readNonExistentErr: %s: want=%v, got=%v", test.what, test.readNonExistentErr, readNonExistentErr) 656 assert.Equal(t, test.writeNonExistentErr, writeNonExistentErr, "writeNonExistentErr: %s: want=%v, got=%v", test.what, test.writeNonExistentErr, writeNonExistentErr) 657 assert.Equal(t, test.openExistingErr, openExistingErr, "openExistingErr: %s: want=%v, got=%v", test.what, test.openExistingErr, openExistingErr) 658 assert.Equal(t, test.readExistingErr, readExistingErr, "readExistingErr: %s: want=%v, got=%v", test.what, test.readExistingErr, readExistingErr) 659 assert.Equal(t, test.writeExistingErr, writeExistingErr, "writeExistingErr: %s: want=%v, got=%v", test.what, test.writeExistingErr, writeExistingErr) 660 assert.Equal(t, test.contents, contents, test.what) 661 } 662 663 func TestRWFileHandleOpenTests(t *testing.T) { 664 r := fstest.NewRun(t) 665 opt := vfscommon.DefaultOpt 666 opt.CacheMode = vfscommon.CacheModeFull 667 vfs := New(r.Fremote, &opt) 668 defer cleanup(t, r, vfs) 669 670 for _, test := range openTests { 671 testRWFileHandleOpenTest(t, vfs, &test) 672 } 673 } 674 675 // tests mod time on open files 676 func TestRWFileModTimeWithOpenWriters(t *testing.T) { 677 r := fstest.NewRun(t) 678 defer r.Finalise() 679 if !canSetModTime(t, r) { 680 return 681 } 682 vfs, fh := rwHandleCreateWriteOnly(t, r) 683 684 mtime := time.Date(2012, time.November, 18, 17, 32, 31, 0, time.UTC) 685 686 _, err := fh.Write([]byte{104, 105}) 687 require.NoError(t, err) 688 689 err = fh.Node().SetModTime(mtime) 690 require.NoError(t, err) 691 692 // Using Flush/Release to mimic mount instead of Close 693 694 err = fh.Flush() 695 require.NoError(t, err) 696 697 err = fh.Release() 698 require.NoError(t, err) 699 700 info, err := vfs.Stat("file1") 701 require.NoError(t, err) 702 703 if r.Fremote.Precision() != fs.ModTimeNotSupported { 704 // avoid errors because of timezone differences 705 assert.Equal(t, info.ModTime().Unix(), mtime.Unix(), fmt.Sprintf("Time mismatch: %v != %v", info.ModTime(), mtime)) 706 } 707 708 file1 := fstest.NewItem("file1", "hi", mtime) 709 fstest.CheckItems(t, r.Fremote, file1) 710 } 711 712 func TestRWCacheRename(t *testing.T) { 713 r := fstest.NewRun(t) 714 defer r.Finalise() 715 716 if !operations.CanServerSideMove(r.Fremote) { 717 t.Skip("skip as can't rename files") 718 } 719 720 opt := vfscommon.DefaultOpt 721 opt.CacheMode = vfscommon.CacheModeFull 722 vfs := New(r.Fremote, &opt) 723 724 h, err := vfs.OpenFile("rename_me", os.O_WRONLY|os.O_CREATE, 0777) 725 require.NoError(t, err) 726 _, err = h.WriteString("hello") 727 require.NoError(t, err) 728 fh, ok := h.(*RWFileHandle) 729 require.True(t, ok) 730 731 err = fh.Sync() 732 require.NoError(t, err) 733 err = fh.Close() 734 require.NoError(t, err) 735 736 assert.True(t, vfs.cache.Exists("rename_me")) 737 738 err = vfs.Rename("rename_me", "i_was_renamed") 739 require.NoError(t, err) 740 741 assert.False(t, vfs.cache.Exists("rename_me")) 742 assert.True(t, vfs.cache.Exists("i_was_renamed")) 743 }