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