OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "base/basictypes.h" | 5 #include "base/basictypes.h" |
6 #include "base/bind.h" | 6 #include "base/bind.h" |
7 #include "base/run_loop.h" | 7 #include "base/run_loop.h" |
8 #include "base/stl_util.h" | 8 #include "base/stl_util.h" |
9 #include "base/synchronization/waitable_event.h" | 9 #include "base/synchronization/waitable_event.h" |
10 #include "chrome/browser/sync_file_system/local_file_sync_service.h" | 10 #include "chrome/browser/sync_file_system/local_file_sync_service.h" |
(...skipping 26 matching lines...) Expand all Loading... |
37 using ::testing::StrictMock; | 37 using ::testing::StrictMock; |
38 using ::testing::_; | 38 using ::testing::_; |
39 | 39 |
40 namespace sync_file_system { | 40 namespace sync_file_system { |
41 | 41 |
42 namespace { | 42 namespace { |
43 | 43 |
44 const char kOrigin[] = "http://example.com"; | 44 const char kOrigin[] = "http://example.com"; |
45 const char kServiceName[] = "test"; | 45 const char kServiceName[] = "test"; |
46 | 46 |
| 47 template <typename R> struct AssignTrait { |
| 48 typedef const R& ArgumentType; |
| 49 }; |
| 50 |
| 51 template <> struct AssignTrait<fileapi::SyncFileStatus> { |
| 52 typedef fileapi::SyncFileStatus ArgumentType; |
| 53 }; |
| 54 |
47 template <typename R> | 55 template <typename R> |
48 void AssignValueAndQuit(base::RunLoop* run_loop, | 56 void AssignValueAndQuit(base::RunLoop* run_loop, |
49 SyncStatusCode* status_out, R* value_out, | 57 SyncStatusCode* status_out, R* value_out, |
50 SyncStatusCode status, const R& value) { | 58 SyncStatusCode status, |
| 59 typename AssignTrait<R>::ArgumentType value) { |
51 DCHECK(status_out); | 60 DCHECK(status_out); |
52 DCHECK(value_out); | 61 DCHECK(value_out); |
53 DCHECK(run_loop); | 62 DCHECK(run_loop); |
54 *status_out = status; | 63 *status_out = status; |
55 *value_out = value; | 64 *value_out = value; |
56 run_loop->Quit(); | 65 run_loop->Quit(); |
57 } | 66 } |
58 | 67 |
59 // This is called on IO thread. | 68 // This is called on IO thread. |
60 void VerifyFileError(base::WaitableEvent* event, | 69 void VerifyFileError(base::WaitableEvent* event, |
(...skipping 439 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
500 EXPECT_CALL(*mock_remote_service(), GetLocalChangeProcessor()) | 509 EXPECT_CALL(*mock_remote_service(), GetLocalChangeProcessor()) |
501 .WillRepeatedly(Return(&local_change_processor)); | 510 .WillRepeatedly(Return(&local_change_processor)); |
502 | 511 |
503 { | 512 { |
504 InSequence sequence; | 513 InSequence sequence; |
505 | 514 |
506 // Return with SYNC_STATUS_FILE_BUSY once. | 515 // Return with SYNC_STATUS_FILE_BUSY once. |
507 EXPECT_CALL(*mock_remote_service(), ProcessRemoteChange(_, _)) | 516 EXPECT_CALL(*mock_remote_service(), ProcessRemoteChange(_, _)) |
508 .WillOnce(MockSyncOperationCallback(fileapi::SYNC_STATUS_FILE_BUSY, | 517 .WillOnce(MockSyncOperationCallback(fileapi::SYNC_STATUS_FILE_BUSY, |
509 kFile, | 518 kFile, |
510 fileapi::SYNC_OPERATION_NONE)) | 519 fileapi::SYNC_OPERATION_NONE)); |
511 .RetiresOnSaturation(); | |
512 | 520 |
513 // ProcessRemoteChange should be called again when the becomes | 521 // ProcessRemoteChange should be called again when the becomes |
514 // not busy. | 522 // not busy. |
515 EXPECT_CALL(*mock_remote_service(), ProcessRemoteChange(_, _)) | 523 EXPECT_CALL(*mock_remote_service(), ProcessRemoteChange(_, _)) |
516 .WillOnce(InvokeWithoutArgs(&run_loop, &base::RunLoop::Quit)); | 524 .WillOnce(InvokeWithoutArgs(&run_loop, &base::RunLoop::Quit)); |
517 } | 525 } |
518 | 526 |
519 // We might also see an activity for local sync as we're going to make | 527 // We might also see an activity for local sync as we're going to make |
520 // a local write operation on kFile. | 528 // a local write operation on kFile. |
521 EXPECT_CALL(local_change_processor, ApplyLocalChange(_, _, _, kFile, _)) | 529 EXPECT_CALL(local_change_processor, ApplyLocalChange(_, _, _, kFile, _)) |
522 .Times(AnyNumber()); | 530 .Times(AnyNumber()); |
523 | 531 |
524 // This should trigger a remote sync. | 532 // This should trigger a remote sync. |
525 mock_remote_service()->NotifyRemoteChangeAvailable(1); | 533 mock_remote_service()->NotifyRemoteChangeAvailable(1); |
526 | 534 |
527 // Start a local operation on the same file (to make it BUSY). | 535 // Start a local operation on the same file (to make it BUSY). |
528 base::WaitableEvent event(false, false); | 536 base::WaitableEvent event(false, false); |
529 thread_helper_.io_task_runner()->PostTask( | 537 thread_helper_.io_task_runner()->PostTask( |
530 FROM_HERE, base::Bind(&fileapi::CannedSyncableFileSystem::DoCreateFile, | 538 FROM_HERE, base::Bind(&fileapi::CannedSyncableFileSystem::DoCreateFile, |
531 base::Unretained(file_system_.get()), | 539 base::Unretained(file_system_.get()), |
532 kFile, base::Bind(&VerifyFileError, &event))); | 540 kFile, base::Bind(&VerifyFileError, &event))); |
533 | 541 |
534 run_loop.Run(); | 542 run_loop.Run(); |
535 | 543 |
536 mock_remote_service()->NotifyRemoteChangeAvailable(0); | 544 mock_remote_service()->NotifyRemoteChangeAvailable(0); |
537 | 545 |
538 event.Wait(); | 546 event.Wait(); |
539 } | 547 } |
540 | 548 |
| 549 TEST_F(SyncFileSystemServiceTest, GetFileSyncStatus) { |
| 550 InitializeApp(); |
| 551 |
| 552 const FileSystemURL kFile(file_system_->URL("foo")); |
| 553 |
| 554 fileapi::SyncStatusCode status; |
| 555 fileapi::SyncFileStatus sync_file_status; |
| 556 |
| 557 // 1. The file is not in conflicting nor in pending change state. |
| 558 { |
| 559 base::RunLoop run_loop; |
| 560 EXPECT_CALL(*mock_remote_service(), IsConflicting(kFile)) |
| 561 .WillOnce(Return(false)); |
| 562 |
| 563 status = fileapi::SYNC_STATUS_UNKNOWN; |
| 564 sync_file_status = fileapi::SYNC_FILE_STATUS_UNKNOWN; |
| 565 sync_service_->GetFileSyncStatus( |
| 566 kFile, |
| 567 base::Bind(&AssignValueAndQuit<fileapi::SyncFileStatus>, |
| 568 &run_loop, &status, &sync_file_status)); |
| 569 run_loop.Run(); |
| 570 |
| 571 EXPECT_EQ(fileapi::SYNC_STATUS_OK, status); |
| 572 EXPECT_EQ(fileapi::SYNC_FILE_STATUS_SYNCED, sync_file_status); |
| 573 } |
| 574 |
| 575 // 2. Conflicting case. |
| 576 { |
| 577 base::RunLoop run_loop; |
| 578 EXPECT_CALL(*mock_remote_service(), IsConflicting(kFile)) |
| 579 .WillOnce(Return(true)); |
| 580 |
| 581 status = fileapi::SYNC_STATUS_UNKNOWN; |
| 582 sync_file_status = fileapi::SYNC_FILE_STATUS_UNKNOWN; |
| 583 sync_service_->GetFileSyncStatus( |
| 584 kFile, |
| 585 base::Bind(&AssignValueAndQuit<fileapi::SyncFileStatus>, |
| 586 &run_loop, &status, &sync_file_status)); |
| 587 run_loop.Run(); |
| 588 |
| 589 EXPECT_EQ(fileapi::SYNC_STATUS_OK, status); |
| 590 EXPECT_EQ(fileapi::SYNC_FILE_STATUS_CONFLICTING, sync_file_status); |
| 591 } |
| 592 |
| 593 // 3. The file has pending local changes. |
| 594 { |
| 595 EXPECT_EQ(base::PLATFORM_FILE_OK, file_system_->CreateFile(kFile)); |
| 596 |
| 597 base::RunLoop run_loop; |
| 598 EXPECT_CALL(*mock_remote_service(), IsConflicting(kFile)) |
| 599 .WillOnce(Return(false)); |
| 600 |
| 601 status = fileapi::SYNC_STATUS_UNKNOWN; |
| 602 sync_file_status = fileapi::SYNC_FILE_STATUS_UNKNOWN; |
| 603 sync_service_->GetFileSyncStatus( |
| 604 kFile, |
| 605 base::Bind(&AssignValueAndQuit<fileapi::SyncFileStatus>, |
| 606 &run_loop, &status, &sync_file_status)); |
| 607 run_loop.Run(); |
| 608 |
| 609 EXPECT_EQ(fileapi::SYNC_STATUS_OK, status); |
| 610 EXPECT_EQ(fileapi::SYNC_FILE_STATUS_HAS_PENDING_CHANGES, sync_file_status); |
| 611 } |
| 612 |
| 613 // 4. The file has a conflict and pending local changes. In this case |
| 614 // we return SYNC_FILE_STATUS_CONFLICTING. |
| 615 { |
| 616 EXPECT_EQ(base::PLATFORM_FILE_OK, file_system_->TruncateFile(kFile, 1U)); |
| 617 |
| 618 base::RunLoop run_loop; |
| 619 EXPECT_CALL(*mock_remote_service(), IsConflicting(kFile)) |
| 620 .WillOnce(Return(true)); |
| 621 |
| 622 status = fileapi::SYNC_STATUS_UNKNOWN; |
| 623 sync_file_status = fileapi::SYNC_FILE_STATUS_UNKNOWN; |
| 624 sync_service_->GetFileSyncStatus( |
| 625 kFile, |
| 626 base::Bind(&AssignValueAndQuit<fileapi::SyncFileStatus>, |
| 627 &run_loop, &status, &sync_file_status)); |
| 628 run_loop.Run(); |
| 629 |
| 630 EXPECT_EQ(fileapi::SYNC_STATUS_OK, status); |
| 631 EXPECT_EQ(fileapi::SYNC_FILE_STATUS_CONFLICTING, sync_file_status); |
| 632 } |
| 633 } |
| 634 |
541 } // namespace sync_file_system | 635 } // namespace sync_file_system |
OLD | NEW |