Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(162)

Side by Side Diff: chrome/browser/sync/engine/syncer_unittest.cc

Issue 2844037: Fix handling of undeletion within the syncer. (Closed) Base URL: http://src.chromium.org/git/chromium.git
Patch Set: Whitespace. Created 10 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2009 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 // Syncer unit tests. Unfortunately a lot of these tests 5 // Syncer unit tests. Unfortunately a lot of these tests
6 // are outdated and need to be reworked and updated. 6 // are outdated and need to be reworked and updated.
7 7
8 #include <list> 8 #include <list>
9 #include <map> 9 #include <map>
10 #include <set> 10 #include <set>
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after
77 using syncable::PREV_ID; 77 using syncable::PREV_ID;
78 using syncable::SERVER_IS_DEL; 78 using syncable::SERVER_IS_DEL;
79 using syncable::SERVER_NON_UNIQUE_NAME; 79 using syncable::SERVER_NON_UNIQUE_NAME;
80 using syncable::SERVER_PARENT_ID; 80 using syncable::SERVER_PARENT_ID;
81 using syncable::SERVER_POSITION_IN_PARENT; 81 using syncable::SERVER_POSITION_IN_PARENT;
82 using syncable::SERVER_SPECIFICS; 82 using syncable::SERVER_SPECIFICS;
83 using syncable::SERVER_VERSION; 83 using syncable::SERVER_VERSION;
84 using syncable::UNIQUE_CLIENT_TAG; 84 using syncable::UNIQUE_CLIENT_TAG;
85 using syncable::UNIQUE_SERVER_TAG; 85 using syncable::UNIQUE_SERVER_TAG;
86 using syncable::SPECIFICS; 86 using syncable::SPECIFICS;
87 using syncable::SYNCING;
87 using syncable::UNITTEST; 88 using syncable::UNITTEST;
88 89
89 using sessions::ConflictProgress; 90 using sessions::ConflictProgress;
90 using sessions::ScopedSetSessionWriteTransaction; 91 using sessions::ScopedSetSessionWriteTransaction;
91 using sessions::StatusController; 92 using sessions::StatusController;
92 using sessions::SyncSessionContext; 93 using sessions::SyncSessionContext;
93 using sessions::SyncSession; 94 using sessions::SyncSession;
94 95
95 class SyncerTest : public testing::Test, 96 class SyncerTest : public testing::Test,
96 public SyncSession::Delegate, 97 public SyncSession::Delegate,
(...skipping 287 matching lines...) Expand 10 before | Expand all | Expand 10 after
384 void EnableDatatype(syncable::ModelType model_type) { 385 void EnableDatatype(syncable::ModelType model_type) {
385 enabled_datatypes_[model_type] = true; 386 enabled_datatypes_[model_type] = true;
386 mock_server_->ExpectGetUpdatesRequestTypes(enabled_datatypes_); 387 mock_server_->ExpectGetUpdatesRequestTypes(enabled_datatypes_);
387 } 388 }
388 389
389 void DisableDatatype(syncable::ModelType model_type) { 390 void DisableDatatype(syncable::ModelType model_type) {
390 enabled_datatypes_[model_type] = false; 391 enabled_datatypes_[model_type] = false;
391 mock_server_->ExpectGetUpdatesRequestTypes(enabled_datatypes_); 392 mock_server_->ExpectGetUpdatesRequestTypes(enabled_datatypes_);
392 } 393 }
393 394
395 template<typename FieldType, typename ValueType>
396 ValueType GetField(int64 metahandle, FieldType field,
397 ValueType default_value) const {
398 ScopedDirLookup dir(syncdb_.manager(), syncdb_.name());
399 EXPECT_TRUE(dir.good());
400 ReadTransaction trans(dir, __FILE__, __LINE__);
401 Entry entry(&trans, GET_BY_HANDLE, metahandle);
402 EXPECT_TRUE(entry.good());
403 if (!entry.good()) {
404 return default_value;
405 }
406 EXPECT_EQ(metahandle, entry.Get(META_HANDLE));
407 return entry.Get(field);
408 }
409
410 // Helper getters that work without a transaction, to reduce boilerplate.
411 Id Get(int64 metahandle, syncable::IdField field) const {
412 return GetField(metahandle, field, syncable::kNullId);
413 }
414
415 string Get(int64 metahandle, syncable::StringField field) const {
416 return GetField(metahandle, field, string());
417 }
418
419 int64 Get(int64 metahandle, syncable::Int64Field field) const {
420 return GetField(metahandle, field, syncable::kInvalidMetaHandle);
421 }
422
423 int64 Get(int64 metahandle, syncable::BaseVersion field) const {
424 const int64 kDefaultValue = -100;
425 return GetField(metahandle, field, kDefaultValue);
426 }
427
428 bool Get(int64 metahandle, syncable::IndexedBitField field) const {
429 return GetField(metahandle, field, false);
430 }
431
432 bool Get(int64 metahandle, syncable::IsDelField field) const {
433 return GetField(metahandle, field, false);
434 }
435
436 bool Get(int64 metahandle, syncable::BitField field) const {
437 return GetField(metahandle, field, false);
438 }
439
394 // Some ids to aid tests. Only the root one's value is specific. The rest 440 // Some ids to aid tests. Only the root one's value is specific. The rest
395 // are named for test clarity. 441 // are named for test clarity.
396 // TODO(chron): Get rid of these inbuilt IDs. They only make it 442 // TODO(chron): Get rid of these inbuilt IDs. They only make it
397 // more confusing. 443 // more confusing.
398 syncable::Id root_id_; 444 syncable::Id root_id_;
399 syncable::Id parent_id_; 445 syncable::Id parent_id_;
400 syncable::Id child_id_; 446 syncable::Id child_id_;
401 447
402 TestIdFactory ids_; 448 TestIdFactory ids_;
403 449
(...skipping 1229 matching lines...) Expand 10 before | Expand all | Expand 10 after
1633 "bob"); 1679 "bob");
1634 CHECK(entry2.good()); 1680 CHECK(entry2.good());
1635 entry2.Put(syncable::IS_DIR, true); 1681 entry2.Put(syncable::IS_DIR, true);
1636 entry2.Put(syncable::IS_UNSYNCED, true); 1682 entry2.Put(syncable::IS_UNSYNCED, true);
1637 entry2.Put(syncable::SPECIFICS, DefaultBookmarkSpecifics()); 1683 entry2.Put(syncable::SPECIFICS, DefaultBookmarkSpecifics());
1638 } 1684 }
1639 }; 1685 };
1640 1686
1641 TEST_F(EntryCreatedInNewFolderTest, EntryCreatedInNewFolderMidSync) { 1687 TEST_F(EntryCreatedInNewFolderTest, EntryCreatedInNewFolderMidSync) {
1642 ScopedDirLookup dir(syncdb_.manager(), syncdb_.name()); 1688 ScopedDirLookup dir(syncdb_.manager(), syncdb_.name());
1643 CHECK(dir.good()); 1689 ASSERT_TRUE(dir.good());
1690 dir->set_store_birthday(mock_server_->store_birthday());
1644 { 1691 {
1645 WriteTransaction trans(dir, UNITTEST, __FILE__, __LINE__); 1692 WriteTransaction trans(dir, UNITTEST, __FILE__, __LINE__);
1646 MutableEntry entry(&trans, syncable::CREATE, trans.root_id(), 1693 MutableEntry entry(&trans, syncable::CREATE, trans.root_id(),
1647 "bob"); 1694 "bob");
1648 ASSERT_TRUE(entry.good()); 1695 ASSERT_TRUE(entry.good());
1649 entry.Put(syncable::IS_DIR, true); 1696 entry.Put(syncable::IS_DIR, true);
1650 entry.Put(syncable::IS_UNSYNCED, true); 1697 entry.Put(syncable::IS_UNSYNCED, true);
1651 entry.Put(syncable::SPECIFICS, DefaultBookmarkSpecifics()); 1698 entry.Put(syncable::SPECIFICS, DefaultBookmarkSpecifics());
1652 } 1699 }
1653 1700
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
1702 WriteTransaction trans(dir, UNITTEST, __FILE__, __LINE__); 1749 WriteTransaction trans(dir, UNITTEST, __FILE__, __LINE__);
1703 MutableEntry fred_match(&trans, GET_BY_HANDLE, metahandle_fred); 1750 MutableEntry fred_match(&trans, GET_BY_HANDLE, metahandle_fred);
1704 ASSERT_TRUE(fred_match.good()); 1751 ASSERT_TRUE(fred_match.good());
1705 EXPECT_TRUE(fred_match.Get(ID).ServerKnows()); 1752 EXPECT_TRUE(fred_match.Get(ID).ServerKnows());
1706 fred_match_id = fred_match.Get(ID); 1753 fred_match_id = fred_match.Get(ID);
1707 mock_server_->AddUpdateBookmark(fred_match_id, trans.root_id(), 1754 mock_server_->AddUpdateBookmark(fred_match_id, trans.root_id(),
1708 "fred_match", 40, 40); 1755 "fred_match", 40, 40);
1709 } 1756 }
1710 // Run the syncer. 1757 // Run the syncer.
1711 for (int i = 0 ; i < 30 ; ++i) { 1758 for (int i = 0 ; i < 30 ; ++i) {
1712 syncer_->SyncShare(this); 1759 syncer_->SyncShare(this);
1713 } 1760 }
1714 } 1761 }
1715 1762
1716 /** 1763 /**
1717 * In the event that we have a double changed entry, that is changed on both 1764 * In the event that we have a double changed entry, that is changed on both
1718 * the client and the server, the conflict resolver should just drop one of 1765 * the client and the server, the conflict resolver should just drop one of
1719 * them and accept the other. 1766 * them and accept the other.
1720 */ 1767 */
1721 1768
1722 TEST_F(SyncerTest, DoublyChangedWithResolver) { 1769 TEST_F(SyncerTest, DoublyChangedWithResolver) {
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
1782 int64 server_position_in_parent; 1829 int64 server_position_in_parent;
1783 { 1830 {
1784 ReadTransaction trans(dir, __FILE__, __LINE__); 1831 ReadTransaction trans(dir, __FILE__, __LINE__);
1785 Entry entry(&trans, syncable::GET_BY_HANDLE, entry_metahandle); 1832 Entry entry(&trans, syncable::GET_BY_HANDLE, entry_metahandle);
1786 ASSERT_TRUE(entry.good()); 1833 ASSERT_TRUE(entry.good());
1787 id = entry.Get(ID); 1834 id = entry.Get(ID);
1788 EXPECT_TRUE(id.ServerKnows()); 1835 EXPECT_TRUE(id.ServerKnows());
1789 version = entry.Get(BASE_VERSION); 1836 version = entry.Get(BASE_VERSION);
1790 server_position_in_parent = entry.Get(SERVER_POSITION_IN_PARENT); 1837 server_position_in_parent = entry.Get(SERVER_POSITION_IN_PARENT);
1791 } 1838 }
1792 mock_server_->AddUpdateDirectory(id, root_id_, "Pete", version, 10); 1839 sync_pb::SyncEntity* update = mock_server_->AddUpdateFromLastCommit();
1793 mock_server_->SetLastUpdatePosition(server_position_in_parent); 1840 EXPECT_EQ("Pete", update->name());
1841 EXPECT_EQ(id.GetServerId(), update->id_string());
1842 EXPECT_EQ(root_id_.GetServerId(), update->parent_id_string());
1843 EXPECT_EQ(version, update->version());
1844 EXPECT_EQ(server_position_in_parent, update->position_in_parent());
1794 syncer_->SyncShare(this); 1845 syncer_->SyncShare(this);
1795 { 1846 {
1796 ReadTransaction trans(dir, __FILE__, __LINE__); 1847 ReadTransaction trans(dir, __FILE__, __LINE__);
1797 Entry entry(&trans, syncable::GET_BY_ID, id); 1848 Entry entry(&trans, syncable::GET_BY_ID, id);
1798 ASSERT_TRUE(entry.good()); 1849 ASSERT_TRUE(entry.good());
1799 EXPECT_TRUE(entry.Get(MTIME) == test_time); 1850 EXPECT_TRUE(entry.Get(MTIME) == test_time);
1800 } 1851 }
1801 } 1852 }
1802 1853
1803 TEST_F(SyncerTest, ParentAndChildBothMatch) { 1854 TEST_F(SyncerTest, ParentAndChildBothMatch) {
(...skipping 736 matching lines...) Expand 10 before | Expand all | Expand 10 after
2540 Entry fred(&trans, GET_BY_ID, fred_id); 2591 Entry fred(&trans, GET_BY_ID, fred_id);
2541 ASSERT_TRUE(fred.good()); 2592 ASSERT_TRUE(fred.good());
2542 EXPECT_FALSE(fred.Get(IS_UNSYNCED)); 2593 EXPECT_FALSE(fred.Get(IS_UNSYNCED));
2543 EXPECT_TRUE(fred.Get(IS_UNAPPLIED_UPDATE)); 2594 EXPECT_TRUE(fred.Get(IS_UNAPPLIED_UPDATE));
2544 EXPECT_TRUE(bob.Get(PARENT_ID) == fred.Get(ID)); 2595 EXPECT_TRUE(bob.Get(PARENT_ID) == fred.Get(ID));
2545 EXPECT_FALSE(bob.Get(IS_UNAPPLIED_UPDATE)); 2596 EXPECT_FALSE(bob.Get(IS_UNAPPLIED_UPDATE));
2546 } 2597 }
2547 syncer_events_.clear(); 2598 syncer_events_.clear();
2548 } 2599 }
2549 2600
2550
2551 TEST_F(SyncerTest, WeMovedSomethingIntoAFolderServerHasDeleted) { 2601 TEST_F(SyncerTest, WeMovedSomethingIntoAFolderServerHasDeleted) {
2552 ScopedDirLookup dir(syncdb_.manager(), syncdb_.name()); 2602 ScopedDirLookup dir(syncdb_.manager(), syncdb_.name());
2553 CHECK(dir.good()); 2603 CHECK(dir.good());
2554 2604
2555 syncable::Id bob_id = ids_.NewServerId(); 2605 syncable::Id bob_id = ids_.NewServerId();
2556 syncable::Id fred_id = ids_.NewServerId(); 2606 syncable::Id fred_id = ids_.NewServerId();
2557 2607
2558 mock_server_->AddUpdateDirectory(bob_id, TestIdFactory::root(), 2608 mock_server_->AddUpdateDirectory(bob_id, TestIdFactory::root(),
2559 "bob", 1, 10); 2609 "bob", 1, 10);
2560 mock_server_->AddUpdateDirectory(fred_id, TestIdFactory::root(), 2610 mock_server_->AddUpdateDirectory(fred_id, TestIdFactory::root(),
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
2597 EXPECT_TRUE(bob.Get(PARENT_ID) == fred.Get(ID)); 2647 EXPECT_TRUE(bob.Get(PARENT_ID) == fred.Get(ID));
2598 EXPECT_TRUE(fred.Get(PARENT_ID) == root_id_); 2648 EXPECT_TRUE(fred.Get(PARENT_ID) == root_id_);
2599 EXPECT_FALSE(fred.Get(IS_UNAPPLIED_UPDATE)); 2649 EXPECT_FALSE(fred.Get(IS_UNAPPLIED_UPDATE));
2600 EXPECT_FALSE(bob.Get(IS_UNAPPLIED_UPDATE)); 2650 EXPECT_FALSE(bob.Get(IS_UNAPPLIED_UPDATE));
2601 } 2651 }
2602 syncer_events_.clear(); 2652 syncer_events_.clear();
2603 } 2653 }
2604 2654
2605 class FolderMoveDeleteRenameTest : public SyncerTest { 2655 class FolderMoveDeleteRenameTest : public SyncerTest {
2606 public: 2656 public:
2607 FolderMoveDeleteRenameTest() : move_bob_count_(0), done_(false) {} 2657 FolderMoveDeleteRenameTest() : done_(false) {}
2608 2658
2609 static const int64 bob_id_number = 1; 2659 static const int64 bob_id_number = 1;
2610 static const int64 fred_id_number = 2; 2660 static const int64 fred_id_number = 2;
2611 2661
2612 void MoveBobIntoID2Runner() { 2662 void MoveBobIntoID2Runner() {
2613 if (!done_) { 2663 if (!done_) {
2614 done_ = MoveBobIntoID2(); 2664 MoveBobIntoID2();
2665 done_ = true;
2615 } 2666 }
2616 } 2667 }
2617 2668
2618 protected: 2669 protected:
2619 int move_bob_count_; 2670 void MoveBobIntoID2() {
2620 bool done_;
2621
2622 bool MoveBobIntoID2() {
2623 ScopedDirLookup dir(syncdb_.manager(), syncdb_.name()); 2671 ScopedDirLookup dir(syncdb_.manager(), syncdb_.name());
2624 CHECK(dir.good()); 2672 CHECK(dir.good());
2625 2673
2626 if (--move_bob_count_ > 0) {
2627 return false;
2628 }
2629
2630 if (move_bob_count_ == 0) {
2631 WriteTransaction trans(dir, UNITTEST, __FILE__, __LINE__); 2674 WriteTransaction trans(dir, UNITTEST, __FILE__, __LINE__);
2632 Entry alice(&trans, GET_BY_ID, 2675 Entry alice(&trans, GET_BY_ID,
2633 TestIdFactory::FromNumber(fred_id_number)); 2676 TestIdFactory::FromNumber(fred_id_number));
2634 CHECK(alice.good()); 2677 CHECK(alice.good());
2635 CHECK(!alice.Get(IS_DEL)); 2678 EXPECT_TRUE(!alice.Get(IS_DEL));
2636 MutableEntry bob(&trans, GET_BY_ID, 2679 EXPECT_TRUE(alice.Get(SYNCING)) << "Expected to be called mid-commit.";
2637 TestIdFactory::FromNumber(bob_id_number)); 2680 MutableEntry bob(&trans, GET_BY_ID,
2681 TestIdFactory::FromNumber(bob_id_number));
2638 CHECK(bob.good()); 2682 CHECK(bob.good());
2639 bob.Put(IS_UNSYNCED, true); 2683 bob.Put(IS_UNSYNCED, true);
2684
2685 bob.Put(SYNCING, false);
2640 bob.Put(PARENT_ID, alice.Get(ID)); 2686 bob.Put(PARENT_ID, alice.Get(ID));
2641 return true;
2642 } 2687 }
2643 return false; 2688
2644 } 2689 bool done_;
2645 }; 2690 };
2646 2691
2647 TEST_F(FolderMoveDeleteRenameTest, 2692 TEST_F(FolderMoveDeleteRenameTest,
2648 WeMovedSomethingIntoAFolderServerHasDeletedAndWeRenamed) { 2693 WeMovedSomethingIntoAFolderServerHasDeletedAndWeRenamed) {
2649 ScopedDirLookup dir(syncdb_.manager(), syncdb_.name()); 2694 ScopedDirLookup dir(syncdb_.manager(), syncdb_.name());
2650 CHECK(dir.good()); 2695 CHECK(dir.good());
2651 2696
2652 const syncable::Id bob_id = TestIdFactory::FromNumber( 2697 const syncable::Id bob_id = TestIdFactory::FromNumber(
2653 FolderMoveDeleteRenameTest::bob_id_number); 2698 FolderMoveDeleteRenameTest::bob_id_number);
2654 const syncable::Id fred_id = TestIdFactory::FromNumber( 2699 const syncable::Id fred_id = TestIdFactory::FromNumber(
2655 FolderMoveDeleteRenameTest::fred_id_number); 2700 FolderMoveDeleteRenameTest::fred_id_number);
2656 2701
2657 mock_server_->AddUpdateDirectory(bob_id, TestIdFactory::root(), 2702 mock_server_->AddUpdateDirectory(bob_id, TestIdFactory::root(),
2658 "bob", 1, 10); 2703 "bob", 1, 10);
2659 mock_server_->AddUpdateDirectory(fred_id, TestIdFactory::root(), 2704 mock_server_->AddUpdateDirectory(fred_id, TestIdFactory::root(),
2660 "fred", 1, 10); 2705 "fred", 1, 10);
2661 syncer_->SyncShare(this); 2706 syncer_->SyncShare(this);
2662 { 2707 {
2663 WriteTransaction trans(dir, UNITTEST, __FILE__, __LINE__); 2708 WriteTransaction trans(dir, UNITTEST, __FILE__, __LINE__);
2664 MutableEntry fred(&trans, GET_BY_ID, fred_id); 2709 MutableEntry fred(&trans, GET_BY_ID, fred_id);
2665 ASSERT_TRUE(fred.good()); 2710 ASSERT_TRUE(fred.good());
2666 fred.Put(IS_UNSYNCED, true); 2711 fred.Put(IS_UNSYNCED, true);
2712 fred.Put(SYNCING, false);
2667 fred.Put(NON_UNIQUE_NAME, "Alice"); 2713 fred.Put(NON_UNIQUE_NAME, "Alice");
2668 } 2714 }
2669 mock_server_->AddUpdateDirectory(fred_id, TestIdFactory::root(), 2715 mock_server_->AddUpdateDirectory(fred_id, TestIdFactory::root(),
2670 "fred", 2, 20); 2716 "fred", 2, 20);
2671 mock_server_->SetLastUpdateDeleted(); 2717 mock_server_->SetLastUpdateDeleted();
2672 mock_server_->set_conflict_all_commits(true); 2718 mock_server_->set_conflict_all_commits(true);
2673 // This test is a little brittle. We want to move the item into the folder 2719 // This test is a little brittle. We want to move the item into the folder
2674 // such that we think we're dealing with a simple conflict, but in reality 2720 // such that we think we're dealing with a simple conflict, but in reality
2675 // it's actually a conflict set. 2721 // it's actually a conflict set.
2676 move_bob_count_ = 2;
2677 mock_server_->SetMidCommitCallback( 2722 mock_server_->SetMidCommitCallback(
2678 NewCallback<FolderMoveDeleteRenameTest>(this, 2723 NewCallback<FolderMoveDeleteRenameTest>(this,
2679 &FolderMoveDeleteRenameTest::MoveBobIntoID2Runner)); 2724 &FolderMoveDeleteRenameTest::MoveBobIntoID2Runner));
2680 syncer_->SyncShare(this); 2725 syncer_->SyncShare(this);
2681 syncer_->SyncShare(this); 2726 syncer_->SyncShare(this);
2682 syncer_->SyncShare(this); 2727 syncer_->SyncShare(this);
2683 { 2728 {
2684 ReadTransaction trans(dir, __FILE__, __LINE__); 2729 ReadTransaction trans(dir, __FILE__, __LINE__);
2685 Entry bob(&trans, GET_BY_ID, bob_id); 2730 Entry bob(&trans, GET_BY_ID, bob_id);
2686 ASSERT_TRUE(bob.good()); 2731 ASSERT_TRUE(bob.good());
(...skipping 1287 matching lines...) Expand 10 before | Expand all | Expand 10 after
3974 EXPECT_FALSE(rejected_update.good()); 4019 EXPECT_FALSE(rejected_update.good());
3975 4020
3976 Entry perm_folder(&trans, GET_BY_CLIENT_TAG, "permfolder"); 4021 Entry perm_folder(&trans, GET_BY_CLIENT_TAG, "permfolder");
3977 ASSERT_TRUE(perm_folder.good()); 4022 ASSERT_TRUE(perm_folder.good());
3978 EXPECT_FALSE(perm_folder.Get(IS_UNAPPLIED_UPDATE)); 4023 EXPECT_FALSE(perm_folder.Get(IS_UNAPPLIED_UPDATE));
3979 EXPECT_FALSE(perm_folder.Get(IS_UNSYNCED)); 4024 EXPECT_FALSE(perm_folder.Get(IS_UNSYNCED));
3980 EXPECT_EQ(perm_folder.Get(NON_UNIQUE_NAME), "permitem1"); 4025 EXPECT_EQ(perm_folder.Get(NON_UNIQUE_NAME), "permitem1");
3981 } 4026 }
3982 } 4027 }
3983 4028
3984 TEST_F(SyncerTest, ClientTagClientCreatedConflictUpdate) { 4029 TEST_F(SyncerTest, ClientTagUncommittedTagMatchesUpdate) {
3985 ScopedDirLookup dir(syncdb_.manager(), syncdb_.name()); 4030 ScopedDirLookup dir(syncdb_.manager(), syncdb_.name());
3986 EXPECT_TRUE(dir.good()); 4031 EXPECT_TRUE(dir.good());
3987 int64 original_metahandle; 4032 int64 original_metahandle = 0;
4033
4034 sync_pb::EntitySpecifics local_bookmark(DefaultBookmarkSpecifics());
4035 local_bookmark.MutableExtension(sync_pb::bookmark)->
4036 set_url("http://foo/localsite");
4037 sync_pb::EntitySpecifics server_bookmark(DefaultBookmarkSpecifics());
4038 server_bookmark.MutableExtension(sync_pb::bookmark)->
4039 set_url("http://bar/serversite");
3988 4040
3989 { 4041 {
3990 WriteTransaction trans(dir, UNITTEST, __FILE__, __LINE__); 4042 WriteTransaction trans(dir, UNITTEST, __FILE__, __LINE__);
3991 MutableEntry perm_folder(&trans, CREATE, ids_.root(), "clientname"); 4043 MutableEntry perm_folder(&trans, CREATE, ids_.root(), "clientname");
3992 ASSERT_TRUE(perm_folder.good()); 4044 ASSERT_TRUE(perm_folder.good());
3993 perm_folder.Put(UNIQUE_CLIENT_TAG, "clientperm"); 4045 perm_folder.Put(UNIQUE_CLIENT_TAG, "clientperm");
3994 perm_folder.Put(SPECIFICS, DefaultBookmarkSpecifics()); 4046 perm_folder.Put(SPECIFICS, local_bookmark);
3995 perm_folder.Put(IS_UNSYNCED, true); 4047 perm_folder.Put(IS_UNSYNCED, true);
3996 EXPECT_FALSE(perm_folder.Get(IS_UNAPPLIED_UPDATE)); 4048 EXPECT_FALSE(perm_folder.Get(IS_UNAPPLIED_UPDATE));
3997 EXPECT_FALSE(perm_folder.Get(ID).ServerKnows()); 4049 EXPECT_FALSE(perm_folder.Get(ID).ServerKnows());
3998 original_metahandle = perm_folder.Get(META_HANDLE); 4050 original_metahandle = perm_folder.Get(META_HANDLE);
3999 } 4051 }
4000 4052
4001 mock_server_->AddUpdateDirectory(1, 0, "permitem_renamed", 10, 100); 4053 mock_server_->AddUpdateBookmark(1, 0, "permitem_renamed", 10, 100);
4002 mock_server_->SetLastUpdateClientTag("clientperm"); 4054 mock_server_->SetLastUpdateClientTag("clientperm");
4055 mock_server_->GetMutableLastUpdate()->mutable_specifics()->
4056 CopyFrom(server_bookmark);
4003 mock_server_->set_conflict_all_commits(true); 4057 mock_server_->set_conflict_all_commits(true);
4004 4058
4005 syncer_->SyncShare(this); 4059 syncer_->SyncShare(this);
4006 // This should cause client tag overwrite. 4060 // This should cause client tag reunion, preserving the metahandle.
4007 { 4061 {
4008 ReadTransaction trans(dir, __FILE__, __LINE__); 4062 ReadTransaction trans(dir, __FILE__, __LINE__);
4009 4063
4010 Entry perm_folder(&trans, GET_BY_CLIENT_TAG, "clientperm"); 4064 Entry perm_folder(&trans, GET_BY_CLIENT_TAG, "clientperm");
4011 ASSERT_TRUE(perm_folder.good()); 4065 ASSERT_TRUE(perm_folder.good());
4012 EXPECT_FALSE(perm_folder.Get(IS_DEL)); 4066 EXPECT_FALSE(perm_folder.Get(IS_DEL));
4013 EXPECT_FALSE(perm_folder.Get(IS_UNAPPLIED_UPDATE)); 4067 EXPECT_FALSE(perm_folder.Get(IS_UNAPPLIED_UPDATE));
4068 EXPECT_TRUE(perm_folder.Get(IS_UNSYNCED));
4069 EXPECT_EQ(10, perm_folder.Get(BASE_VERSION));
4070 // Entry should have been given the new ID while preserving the
4071 // metahandle; client should have won the conflict resolution.
4072 EXPECT_EQ(original_metahandle, perm_folder.Get(META_HANDLE));
4073 EXPECT_EQ("clientperm", perm_folder.Get(UNIQUE_CLIENT_TAG));
4074 EXPECT_EQ("clientname", perm_folder.Get(NON_UNIQUE_NAME));
4075 EXPECT_EQ(local_bookmark.SerializeAsString(),
4076 perm_folder.Get(SPECIFICS).SerializeAsString());
4077 EXPECT_TRUE(perm_folder.Get(ID).ServerKnows());
4078 }
4079
4080 mock_server_->set_conflict_all_commits(false);
4081 syncer_->SyncShare(this);
4082
4083 // The resolved entry ought to commit cleanly.
4084 {
4085 ReadTransaction trans(dir, __FILE__, __LINE__);
4086
4087 Entry perm_folder(&trans, GET_BY_CLIENT_TAG, "clientperm");
4088 ASSERT_TRUE(perm_folder.good());
4089 EXPECT_FALSE(perm_folder.Get(IS_DEL));
4090 EXPECT_FALSE(perm_folder.Get(IS_UNAPPLIED_UPDATE));
4014 EXPECT_FALSE(perm_folder.Get(IS_UNSYNCED)); 4091 EXPECT_FALSE(perm_folder.Get(IS_UNSYNCED));
4015 EXPECT_EQ(perm_folder.Get(BASE_VERSION), 10); 4092 EXPECT_TRUE(10 < perm_folder.Get(BASE_VERSION));
4016 // Entry should have been moved aside. 4093 // Entry should have been given the new ID while preserving the
4017 EXPECT_NE(perm_folder.Get(META_HANDLE), original_metahandle); 4094 // metahandle; client should have won the conflict resolution.
4018 EXPECT_EQ(perm_folder.Get(UNIQUE_CLIENT_TAG), "clientperm"); 4095 EXPECT_EQ(original_metahandle, perm_folder.Get(META_HANDLE));
4019 EXPECT_TRUE(perm_folder.Get(NON_UNIQUE_NAME) == "permitem_renamed"); 4096 EXPECT_EQ("clientperm", perm_folder.Get(UNIQUE_CLIENT_TAG));
4020 4097 EXPECT_EQ("clientname", perm_folder.Get(NON_UNIQUE_NAME));
4021 Entry moved_aside(&trans, GET_BY_HANDLE, original_metahandle); 4098 EXPECT_EQ(local_bookmark.SerializeAsString(),
4022 EXPECT_TRUE(moved_aside.good()); 4099 perm_folder.Get(SPECIFICS).SerializeAsString());
4023 EXPECT_TRUE(moved_aside.Get(IS_DEL)); 4100 EXPECT_TRUE(perm_folder.Get(ID).ServerKnows());
4024 } 4101 }
4025 } 4102 }
4026 4103
4027 TEST_F(SyncerTest, ClientTagOverwitesDeletedClientEntry) { 4104 TEST_F(SyncerTest, ClientTagConflictWithDeletedLocalEntry) {
4028 ScopedDirLookup dir(syncdb_.manager(), syncdb_.name()); 4105 ScopedDirLookup dir(syncdb_.manager(), syncdb_.name());
4029 EXPECT_TRUE(dir.good()); 4106 EXPECT_TRUE(dir.good());
4030 4107
4031 { 4108 {
4032 WriteTransaction trans(dir, UNITTEST, __FILE__, __LINE__); 4109 WriteTransaction trans(dir, UNITTEST, __FILE__, __LINE__);
4033 MutableEntry perm_folder(&trans, CREATE, ids_.root(), "clientname"); 4110 MutableEntry perm_folder(&trans, CREATE, ids_.root(), "clientname");
4034 ASSERT_TRUE(perm_folder.good()); 4111 ASSERT_TRUE(perm_folder.good());
4112 ASSERT_FALSE(perm_folder.Get(ID).ServerKnows());
4035 perm_folder.Put(UNIQUE_CLIENT_TAG, "clientperm"); 4113 perm_folder.Put(UNIQUE_CLIENT_TAG, "clientperm");
4114 perm_folder.Put(SPECIFICS, DefaultBookmarkSpecifics());
4036 perm_folder.Put(IS_UNSYNCED, true); 4115 perm_folder.Put(IS_UNSYNCED, true);
4037 perm_folder.Put(IS_DEL, true); 4116 perm_folder.Put(IS_DEL, true);
4038 } 4117 }
4039 4118
4040 mock_server_->AddUpdateDirectory(1, 0, "permitem_renamed", 10, 100); 4119 mock_server_->AddUpdateDirectory(1, 0, "permitem_renamed", 10, 100);
4041 mock_server_->SetLastUpdateClientTag("clientperm"); 4120 mock_server_->SetLastUpdateClientTag("clientperm");
4042 mock_server_->set_conflict_all_commits(true); 4121 mock_server_->set_conflict_all_commits(true);
4043 4122
4044 syncer_->SyncShare(this); 4123 syncer_->SyncShare(this);
4045 // This should cause client tag overwrite. 4124 // This should cause client tag overwrite.
4046 { 4125 {
4047 ReadTransaction trans(dir, __FILE__, __LINE__); 4126 ReadTransaction trans(dir, __FILE__, __LINE__);
4048 4127
4049 Entry perm_folder(&trans, GET_BY_CLIENT_TAG, "clientperm"); 4128 Entry perm_folder(&trans, GET_BY_CLIENT_TAG, "clientperm");
4050 ASSERT_TRUE(perm_folder.good()); 4129 ASSERT_TRUE(perm_folder.good());
4051 EXPECT_FALSE(perm_folder.Get(IS_DEL)); 4130 ASSERT_TRUE(perm_folder.Get(ID).ServerKnows());
4131 EXPECT_TRUE(perm_folder.Get(IS_DEL));
4052 EXPECT_FALSE(perm_folder.Get(IS_UNAPPLIED_UPDATE)); 4132 EXPECT_FALSE(perm_folder.Get(IS_UNAPPLIED_UPDATE));
4053 EXPECT_FALSE(perm_folder.Get(IS_UNSYNCED)); 4133 EXPECT_TRUE(perm_folder.Get(IS_UNSYNCED));
4054 EXPECT_EQ(perm_folder.Get(BASE_VERSION), 10); 4134 EXPECT_EQ(perm_folder.Get(BASE_VERSION), 10);
4055 EXPECT_EQ(perm_folder.Get(UNIQUE_CLIENT_TAG), "clientperm"); 4135 EXPECT_EQ(perm_folder.Get(UNIQUE_CLIENT_TAG), "clientperm");
4056 EXPECT_TRUE(perm_folder.Get(NON_UNIQUE_NAME) == "permitem_renamed");
4057 } 4136 }
4058 } 4137 }
4059 4138
4060 TEST_F(SyncerTest, UniqueServerTagUpdates) { 4139 TEST_F(SyncerTest, UniqueServerTagUpdates) {
4061 ScopedDirLookup dir(syncdb_.manager(), syncdb_.name()); 4140 ScopedDirLookup dir(syncdb_.manager(), syncdb_.name());
4062 EXPECT_TRUE(dir.good()); 4141 EXPECT_TRUE(dir.good());
4063 // As a hurdle, introduce an item whose name is the same as the tag value 4142 // As a hurdle, introduce an item whose name is the same as the tag value
4064 // we'll use later. 4143 // we'll use later.
4065 int64 hurdle_handle = CreateUnsyncedDirectory("bob", "id_bob"); 4144 int64 hurdle_handle = CreateUnsyncedDirectory("bob", "id_bob");
4066 { 4145 {
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
4132 DisableDatatype(syncable::AUTOFILL); 4211 DisableDatatype(syncable::AUTOFILL);
4133 syncer_->SyncShare(this); 4212 syncer_->SyncShare(this);
4134 EXPECT_EQ(1, mock_server_->GetAndClearNumGetUpdatesRequests()); 4213 EXPECT_EQ(1, mock_server_->GetAndClearNumGetUpdatesRequests());
4135 4214
4136 DisableDatatype(syncable::PREFERENCES); 4215 DisableDatatype(syncable::PREFERENCES);
4137 EnableDatatype(syncable::AUTOFILL); 4216 EnableDatatype(syncable::AUTOFILL);
4138 syncer_->SyncShare(this); 4217 syncer_->SyncShare(this);
4139 EXPECT_EQ(1, mock_server_->GetAndClearNumGetUpdatesRequests()); 4218 EXPECT_EQ(1, mock_server_->GetAndClearNumGetUpdatesRequests());
4140 } 4219 }
4141 4220
4221 // Test what happens if a client deletes, then recreates, an object very
4222 // quickly. It is possible that the deletion gets sent as a commit, and
4223 // the undelete happens during the commit request. The principle here
4224 // is that with a single committing client, conflicts should never
4225 // be encountered, and a client encountering its past actions during
4226 // getupdates should never feed back to override later actions.
4227 //
4228 // In cases of ordering A-F below, the outcome should be the same.
4229 // Exercised by UndeleteDuringCommit:
4230 // A. Delete - commit - undelete - commitresponse.
4231 // B. Delete - commit - undelete - commitresponse - getupdates.
4232 // Exercised by UndeleteBeforeCommit:
4233 // C. Delete - undelete - commit - commitresponse.
4234 // D. Delete - undelete - commit - commitresponse - getupdates.
4235 // Exercised by UndeleteAfterCommit:
4236 // E. Delete - commit - commitresponse - undelete - commit
4237 // - commitresponse.
4238 // F. Delete - commit - commitresponse - undelete - commit -
4239 // - commitresponse - getupdates.
4240 class SyncerUndeletionTest : public SyncerTest {
4241 public:
4242 SyncerUndeletionTest()
4243 : client_tag_("foobar"),
4244 metahandle_(syncable::kInvalidMetaHandle) {
4245 }
4246
4247 void Create() {
4248 ScopedDirLookup dir(syncdb_.manager(), syncdb_.name());
4249 EXPECT_TRUE(dir.good());
4250 WriteTransaction trans(dir, UNITTEST, __FILE__, __LINE__);
4251 MutableEntry perm_folder(&trans, CREATE, ids_.root(), "clientname");
4252 ASSERT_TRUE(perm_folder.good());
4253 perm_folder.Put(UNIQUE_CLIENT_TAG, client_tag_);
4254 perm_folder.Put(IS_UNSYNCED, true);
4255 perm_folder.Put(SYNCING, false);
4256 perm_folder.Put(SPECIFICS, DefaultBookmarkSpecifics());
4257 EXPECT_FALSE(perm_folder.Get(IS_UNAPPLIED_UPDATE));
4258 EXPECT_FALSE(perm_folder.Get(ID).ServerKnows());
4259 metahandle_ = perm_folder.Get(META_HANDLE);
4260 }
4261
4262 void Delete() {
4263 ScopedDirLookup dir(syncdb_.manager(), syncdb_.name());
4264 EXPECT_TRUE(dir.good());
4265 WriteTransaction trans(dir, UNITTEST, __FILE__, __LINE__);
4266 MutableEntry entry(&trans, GET_BY_CLIENT_TAG, client_tag_);
4267 ASSERT_TRUE(entry.good());
4268 EXPECT_EQ(metahandle_, entry.Get(META_HANDLE));
4269 entry.Put(IS_DEL, true);
4270 entry.Put(IS_UNSYNCED, true);
4271 entry.Put(SYNCING, false);
4272 }
4273
4274 void Undelete() {
4275 ScopedDirLookup dir(syncdb_.manager(), syncdb_.name());
4276 EXPECT_TRUE(dir.good());
4277 WriteTransaction trans(dir, UNITTEST, __FILE__, __LINE__);
4278 MutableEntry entry(&trans, GET_BY_CLIENT_TAG, client_tag_);
4279 ASSERT_TRUE(entry.good());
4280 EXPECT_EQ(metahandle_, entry.Get(META_HANDLE));
4281 EXPECT_TRUE(entry.Get(IS_DEL));
4282 entry.Put(IS_DEL, false);
4283 entry.Put(IS_UNSYNCED, true);
4284 entry.Put(SYNCING, false);
4285 }
4286
4287 int64 GetMetahandleOfTag() {
4288 ScopedDirLookup dir(syncdb_.manager(), syncdb_.name());
4289 EXPECT_TRUE(dir.good());
4290 ReadTransaction trans(dir, __FILE__, __LINE__);
4291 Entry entry(&trans, GET_BY_CLIENT_TAG, client_tag_);
4292 EXPECT_TRUE(entry.good());
4293 if (!entry.good()) {
4294 return syncable::kInvalidMetaHandle;
4295 }
4296 return entry.Get(META_HANDLE);
4297 }
4298
4299 void ExpectUnsyncedCreation() {
4300 EXPECT_EQ(metahandle_, GetMetahandleOfTag());
4301 EXPECT_FALSE(Get(metahandle_, IS_DEL));
4302 EXPECT_FALSE(Get(metahandle_, SERVER_IS_DEL)); // Never been committed.
4303 EXPECT_GE(0, Get(metahandle_, BASE_VERSION));
4304 EXPECT_TRUE(Get(metahandle_, IS_UNSYNCED));
4305 EXPECT_FALSE(Get(metahandle_, IS_UNAPPLIED_UPDATE));
4306 }
4307
4308 void ExpectUnsyncedUndeletion() {
4309 EXPECT_EQ(metahandle_, GetMetahandleOfTag());
4310 EXPECT_FALSE(Get(metahandle_, IS_DEL));
4311 EXPECT_TRUE(Get(metahandle_, SERVER_IS_DEL));
4312 EXPECT_EQ(0, Get(metahandle_, BASE_VERSION));
4313 EXPECT_TRUE(Get(metahandle_, IS_UNSYNCED));
4314 EXPECT_FALSE(Get(metahandle_, IS_UNAPPLIED_UPDATE));
4315 EXPECT_TRUE(Get(metahandle_, ID).ServerKnows());
4316 }
4317
4318 void ExpectUnsyncedEdit() {
4319 EXPECT_EQ(metahandle_, GetMetahandleOfTag());
4320 EXPECT_FALSE(Get(metahandle_, IS_DEL));
4321 EXPECT_FALSE(Get(metahandle_, SERVER_IS_DEL));
4322 EXPECT_LT(0, Get(metahandle_, BASE_VERSION));
4323 EXPECT_TRUE(Get(metahandle_, IS_UNSYNCED));
4324 EXPECT_FALSE(Get(metahandle_, IS_UNAPPLIED_UPDATE));
4325 EXPECT_TRUE(Get(metahandle_, ID).ServerKnows());
4326 }
4327
4328 void ExpectUnsyncedDeletion() {
4329 EXPECT_EQ(metahandle_, GetMetahandleOfTag());
4330 EXPECT_TRUE(Get(metahandle_, IS_DEL));
4331 EXPECT_FALSE(Get(metahandle_, SERVER_IS_DEL));
4332 EXPECT_TRUE(Get(metahandle_, IS_UNSYNCED));
4333 EXPECT_FALSE(Get(metahandle_, IS_UNAPPLIED_UPDATE));
4334 EXPECT_LT(0, Get(metahandle_, BASE_VERSION));
4335 EXPECT_LT(0, Get(metahandle_, SERVER_VERSION));
4336 }
4337
4338 void ExpectSyncedAndCreated() {
4339 EXPECT_EQ(metahandle_, GetMetahandleOfTag());
4340 EXPECT_FALSE(Get(metahandle_, IS_DEL));
4341 EXPECT_FALSE(Get(metahandle_, SERVER_IS_DEL));
4342 EXPECT_LT(0, Get(metahandle_, BASE_VERSION));
4343 EXPECT_EQ(Get(metahandle_, BASE_VERSION), Get(metahandle_, SERVER_VERSION));
4344 EXPECT_FALSE(Get(metahandle_, IS_UNSYNCED));
4345 EXPECT_FALSE(Get(metahandle_, IS_UNAPPLIED_UPDATE));
4346 }
4347
4348 void ExpectSyncedAndDeleted() {
4349 EXPECT_EQ(metahandle_, GetMetahandleOfTag());
4350 EXPECT_TRUE(Get(metahandle_, IS_DEL));
4351 EXPECT_TRUE(Get(metahandle_, SERVER_IS_DEL));
4352 EXPECT_FALSE(Get(metahandle_, IS_UNSYNCED));
4353 EXPECT_FALSE(Get(metahandle_, IS_UNAPPLIED_UPDATE));
4354 EXPECT_GE(0, Get(metahandle_, BASE_VERSION));
4355 EXPECT_GE(0, Get(metahandle_, SERVER_VERSION));
4356 }
4357
4358 protected:
4359 const std::string client_tag_;
4360 int64 metahandle_;
4361 };
4362
4363 TEST_F(SyncerUndeletionTest, UndeleteDuringCommit) {
4364 StatusController* status = session_->status_controller();
4365
4366 Create();
4367 ExpectUnsyncedCreation();
4368 syncer_->SyncShare(this);
4369
4370 EXPECT_EQ(1, mock_server_->GetAndClearNumGetUpdatesRequests());
4371 EXPECT_EQ(0, status->TotalNumConflictingItems());
4372 ExpectSyncedAndCreated();
4373
4374 // Delete, begin committing the delete, then undelete while committing.
4375 Delete();
4376 ExpectUnsyncedDeletion();
4377 mock_server_->SetMidCommitCallback(
4378 NewCallback<SyncerUndeletionTest>(this,
4379 &SyncerUndeletionTest::Undelete));
4380 syncer_->SyncShare(this);
4381
4382 // The item ought to exist as an unsynced undeletion (meaning,
4383 // we think that the next commit ought to be a recreation commit).
4384 EXPECT_EQ(0, status->TotalNumConflictingItems());
4385 EXPECT_EQ(1, mock_server_->GetAndClearNumGetUpdatesRequests());
4386 ExpectUnsyncedUndeletion();
4387
4388 // Now, encounter a GetUpdates corresponding to the deletion from
4389 // the server. The undeletion should prevail again and be committed.
4390 // None of this should trigger any conflict detection -- it is perfectly
4391 // normal to recieve updates from our own commits.
4392 mock_server_->SetMidCommitCallback(NULL);
4393 mock_server_->AddUpdateTombstone(Get(metahandle_, ID));
4394 syncer_->SyncShare(this);
4395 EXPECT_EQ(0, status->TotalNumConflictingItems());
4396 EXPECT_EQ(1, mock_server_->GetAndClearNumGetUpdatesRequests());
4397 ExpectSyncedAndCreated();
4398 }
4399
4400 TEST_F(SyncerUndeletionTest, UndeleteBeforeCommit) {
4401 StatusController* status = session_->status_controller();
4402
4403 Create();
4404 ExpectUnsyncedCreation();
4405 syncer_->SyncShare(this);
4406
4407 EXPECT_EQ(1, mock_server_->GetAndClearNumGetUpdatesRequests());
4408 EXPECT_EQ(0, status->TotalNumConflictingItems());
4409 ExpectSyncedAndCreated();
4410
4411 // Delete and undelete, then sync to pick up the result.
4412 Delete();
4413 ExpectUnsyncedDeletion();
4414 Undelete();
4415 ExpectUnsyncedEdit(); // Edit, not undelete: server thinks it exists.
4416 syncer_->SyncShare(this);
4417
4418 // The item ought to have committed successfully.
4419 EXPECT_EQ(0, status->TotalNumConflictingItems());
4420 EXPECT_EQ(1, mock_server_->GetAndClearNumGetUpdatesRequests());
4421 ExpectSyncedAndCreated();
4422 EXPECT_EQ(2, Get(metahandle_, BASE_VERSION));
4423
4424 // Now, encounter a GetUpdates corresponding to the just-committed
4425 // update.
4426 mock_server_->AddUpdateFromLastCommit();
4427 syncer_->SyncShare(this);
4428 EXPECT_EQ(0, status->TotalNumConflictingItems());
4429 EXPECT_EQ(1, mock_server_->GetAndClearNumGetUpdatesRequests());
4430 ExpectSyncedAndCreated();
4431 }
4432
4433 TEST_F(SyncerUndeletionTest, UndeleteAfterCommitButBeforeGetUpdates) {
4434 StatusController* status = session_->status_controller();
4435
4436 Create();
4437 ExpectUnsyncedCreation();
4438 syncer_->SyncShare(this);
4439
4440 EXPECT_EQ(1, mock_server_->GetAndClearNumGetUpdatesRequests());
4441 EXPECT_EQ(0, status->TotalNumConflictingItems());
4442 ExpectSyncedAndCreated();
4443
4444 // Delete and commit.
4445 Delete();
4446 ExpectUnsyncedDeletion();
4447 syncer_->SyncShare(this);
4448
4449 // The item ought to have committed successfully.
4450 EXPECT_EQ(0, status->TotalNumConflictingItems());
4451 EXPECT_EQ(1, mock_server_->GetAndClearNumGetUpdatesRequests());
4452 ExpectSyncedAndDeleted();
4453
4454 // Before the GetUpdates, the item is locally undeleted.
4455 Undelete();
4456 ExpectUnsyncedUndeletion();
4457
4458 // Now, encounter a GetUpdates corresponding to the just-committed
4459 // deletion update. The undeletion should prevail.
4460 mock_server_->AddUpdateFromLastCommit();
4461 syncer_->SyncShare(this);
4462 EXPECT_EQ(0, status->TotalNumConflictingItems());
4463 EXPECT_EQ(1, mock_server_->GetAndClearNumGetUpdatesRequests());
4464 ExpectSyncedAndCreated();
4465 }
4466
4467 TEST_F(SyncerUndeletionTest, UndeleteAfterDeleteAndGetUpdates) {
4468 StatusController* status = session_->status_controller();
4469
4470 Create();
4471 ExpectUnsyncedCreation();
4472 syncer_->SyncShare(this);
4473
4474 EXPECT_EQ(1, mock_server_->GetAndClearNumGetUpdatesRequests());
4475 EXPECT_EQ(0, status->TotalNumConflictingItems());
4476 ExpectSyncedAndCreated();
4477
4478 mock_server_->AddUpdateFromLastCommit();
4479 syncer_->SyncShare(this);
4480 EXPECT_EQ(1, mock_server_->GetAndClearNumGetUpdatesRequests());
4481 EXPECT_EQ(0, status->TotalNumConflictingItems());
4482 ExpectSyncedAndCreated();
4483
4484 // Delete and commit.
4485 Delete();
4486 ExpectUnsyncedDeletion();
4487 syncer_->SyncShare(this);
4488
4489 // The item ought to have committed successfully.
4490 EXPECT_EQ(0, status->TotalNumConflictingItems());
4491 EXPECT_EQ(1, mock_server_->GetAndClearNumGetUpdatesRequests());
4492 ExpectSyncedAndDeleted();
4493
4494 // Now, encounter a GetUpdates corresponding to the just-committed
4495 // deletion update. Should be consistent.
4496 mock_server_->AddUpdateFromLastCommit();
4497 syncer_->SyncShare(this);
4498 EXPECT_EQ(0, status->TotalNumConflictingItems());
4499 EXPECT_EQ(1, mock_server_->GetAndClearNumGetUpdatesRequests());
4500 ExpectSyncedAndDeleted();
4501
4502 // After the GetUpdates, the item is locally undeleted.
4503 Undelete();
4504 ExpectUnsyncedUndeletion();
4505
4506 // Now, encounter a GetUpdates corresponding to the just-committed
4507 // deletion update. The undeletion should prevail.
4508 syncer_->SyncShare(this);
4509 EXPECT_EQ(0, status->TotalNumConflictingItems());
4510 EXPECT_EQ(1, mock_server_->GetAndClearNumGetUpdatesRequests());
4511 ExpectSyncedAndCreated();
4512 }
4513
4514 // Test processing of undeletion GetUpdateses.
4515 TEST_F(SyncerUndeletionTest, UndeleteAfterOtherClientDeletes) {
4516 StatusController* status = session_->status_controller();
4517
4518 Create();
4519 ExpectUnsyncedCreation();
4520 syncer_->SyncShare(this);
4521
4522 EXPECT_EQ(1, mock_server_->GetAndClearNumGetUpdatesRequests());
4523 EXPECT_EQ(0, status->TotalNumConflictingItems());
4524 ExpectSyncedAndCreated();
4525
4526 // Add a delete from the server.
4527 mock_server_->AddUpdateFromLastCommit();
4528 syncer_->SyncShare(this);
4529 EXPECT_EQ(1, mock_server_->GetAndClearNumGetUpdatesRequests());
4530 EXPECT_EQ(0, status->TotalNumConflictingItems());
4531 ExpectSyncedAndCreated();
4532
4533 // Some other client deletes the item.
4534 mock_server_->AddUpdateTombstone(Get(metahandle_, ID));
4535 syncer_->SyncShare(this);
4536
4537 // The update ought to have applied successfully.
4538 EXPECT_EQ(0, status->TotalNumConflictingItems());
4539 EXPECT_EQ(1, mock_server_->GetAndClearNumGetUpdatesRequests());
4540 ExpectSyncedAndDeleted();
4541
4542 // Undelete it locally.
4543 Undelete();
4544 ExpectUnsyncedUndeletion();
4545 syncer_->SyncShare(this);
4546 EXPECT_EQ(0, status->TotalNumConflictingItems());
4547 EXPECT_EQ(1, mock_server_->GetAndClearNumGetUpdatesRequests());
4548 ExpectSyncedAndCreated();
4549
4550 // Now, encounter a GetUpdates corresponding to the just-committed
4551 // deletion update. The undeletion should prevail.
4552 mock_server_->AddUpdateFromLastCommit();
4553 syncer_->SyncShare(this);
4554 EXPECT_EQ(0, status->TotalNumConflictingItems());
4555 EXPECT_EQ(1, mock_server_->GetAndClearNumGetUpdatesRequests());
4556 ExpectSyncedAndCreated();
4557 }
4558
4559 TEST_F(SyncerUndeletionTest, UndeleteAfterOtherClientDeletesImmediately) {
4560 StatusController* status = session_->status_controller();
4561
4562 Create();
4563 ExpectUnsyncedCreation();
4564 syncer_->SyncShare(this);
4565
4566 EXPECT_EQ(1, mock_server_->GetAndClearNumGetUpdatesRequests());
4567 EXPECT_EQ(0, status->TotalNumConflictingItems());
4568 ExpectSyncedAndCreated();
4569
4570 // Some other client deletes the item before we get a chance
4571 // to GetUpdates our original request.
4572 mock_server_->AddUpdateTombstone(Get(metahandle_, ID));
4573 syncer_->SyncShare(this);
4574
4575 // The update ought to have applied successfully.
4576 EXPECT_EQ(0, status->TotalNumConflictingItems());
4577 EXPECT_EQ(1, mock_server_->GetAndClearNumGetUpdatesRequests());
4578 ExpectSyncedAndDeleted();
4579
4580 // Undelete it locally.
4581 Undelete();
4582 ExpectUnsyncedUndeletion();
4583 syncer_->SyncShare(this);
4584 EXPECT_EQ(0, status->TotalNumConflictingItems());
4585 EXPECT_EQ(1, mock_server_->GetAndClearNumGetUpdatesRequests());
4586 ExpectSyncedAndCreated();
4587
4588 // Now, encounter a GetUpdates corresponding to the just-committed
4589 // deletion update. The undeletion should prevail.
4590 mock_server_->AddUpdateFromLastCommit();
4591 syncer_->SyncShare(this);
4592 EXPECT_EQ(0, status->TotalNumConflictingItems());
4593 EXPECT_EQ(1, mock_server_->GetAndClearNumGetUpdatesRequests());
4594 ExpectSyncedAndCreated();
4595 }
4596
4597 TEST_F(SyncerUndeletionTest, OtherClientUndeletes) {
4598 StatusController* status = session_->status_controller();
4599
4600 Create();
4601 ExpectUnsyncedCreation();
4602 syncer_->SyncShare(this);
4603
4604 EXPECT_EQ(1, mock_server_->GetAndClearNumGetUpdatesRequests());
4605 EXPECT_EQ(0, status->TotalNumConflictingItems());
4606 ExpectSyncedAndCreated();
4607
4608 // Get the updates of our just-committed entry.
4609 mock_server_->AddUpdateFromLastCommit();
4610 syncer_->SyncShare(this);
4611 EXPECT_EQ(1, mock_server_->GetAndClearNumGetUpdatesRequests());
4612 EXPECT_EQ(0, status->TotalNumConflictingItems());
4613 ExpectSyncedAndCreated();
4614
4615 // We delete the item.
4616 Delete();
4617 ExpectUnsyncedDeletion();
4618 syncer_->SyncShare(this);
4619
4620 // The update ought to have applied successfully.
4621 EXPECT_EQ(0, status->TotalNumConflictingItems());
4622 EXPECT_EQ(1, mock_server_->GetAndClearNumGetUpdatesRequests());
4623 ExpectSyncedAndDeleted();
4624
4625 // Now, encounter a GetUpdates corresponding to the just-committed
4626 // deletion update.
4627 mock_server_->AddUpdateFromLastCommit();
4628 syncer_->SyncShare(this);
4629 EXPECT_EQ(0, status->TotalNumConflictingItems());
4630 EXPECT_EQ(1, mock_server_->GetAndClearNumGetUpdatesRequests());
4631 ExpectSyncedAndDeleted();
4632
4633 // Some other client undeletes the item.
4634 mock_server_->AddUpdateBookmark(Get(metahandle_, ID),
4635 Get(metahandle_, PARENT_ID),
4636 "Thadeusz", 100, 1000);
4637 mock_server_->SetLastUpdateClientTag(client_tag_);
4638 syncer_->SyncShare(this);
4639 EXPECT_EQ(0, status->TotalNumConflictingItems());
4640 EXPECT_EQ(1, mock_server_->GetAndClearNumGetUpdatesRequests());
4641 ExpectSyncedAndCreated();
4642 EXPECT_EQ("Thadeusz", Get(metahandle_, NON_UNIQUE_NAME));
4643 }
4644
4645 TEST_F(SyncerUndeletionTest, OtherClientUndeletesImmediately) {
4646 StatusController* status = session_->status_controller();
4647
4648 Create();
4649 ExpectUnsyncedCreation();
4650 syncer_->SyncShare(this);
4651
4652 EXPECT_EQ(1, mock_server_->GetAndClearNumGetUpdatesRequests());
4653 EXPECT_EQ(0, status->TotalNumConflictingItems());
4654 ExpectSyncedAndCreated();
4655
4656 // Get the updates of our just-committed entry.
4657 mock_server_->AddUpdateFromLastCommit();
4658 syncer_->SyncShare(this);
4659 EXPECT_EQ(1, mock_server_->GetAndClearNumGetUpdatesRequests());
4660 EXPECT_EQ(0, status->TotalNumConflictingItems());
4661 ExpectSyncedAndCreated();
4662
4663 // We delete the item.
4664 Delete();
4665 ExpectUnsyncedDeletion();
4666 syncer_->SyncShare(this);
4667
4668 // The update ought to have applied successfully.
4669 EXPECT_EQ(0, status->TotalNumConflictingItems());
4670 EXPECT_EQ(1, mock_server_->GetAndClearNumGetUpdatesRequests());
4671 ExpectSyncedAndDeleted();
4672
4673 // Some other client undeletes before we see the update from our
4674 // commit.
4675 mock_server_->AddUpdateBookmark(Get(metahandle_, ID),
4676 Get(metahandle_, PARENT_ID),
4677 "Thadeusz", 100, 1000);
4678 mock_server_->SetLastUpdateClientTag(client_tag_);
4679 syncer_->SyncShare(this);
4680 EXPECT_EQ(0, status->TotalNumConflictingItems());
4681 EXPECT_EQ(1, mock_server_->GetAndClearNumGetUpdatesRequests());
4682 ExpectSyncedAndCreated();
4683 EXPECT_EQ("Thadeusz", Get(metahandle_, NON_UNIQUE_NAME));
4684 }
4685
4686 // A group of tests exercising the syncer's handling of sibling ordering, as
4687 // represented in the sync protocol.
4142 class SyncerPositionUpdateTest : public SyncerTest { 4688 class SyncerPositionUpdateTest : public SyncerTest {
4143 public: 4689 public:
4144 SyncerPositionUpdateTest() : next_update_id_(1), next_revision_(1) {} 4690 SyncerPositionUpdateTest() : next_update_id_(1), next_revision_(1) {}
4145 4691
4146 protected: 4692 protected:
4147 void ExpectLocalItemsInServerOrder() { 4693 void ExpectLocalItemsInServerOrder() {
4148 if (position_map_.empty()) 4694 if (position_map_.empty())
4149 return; 4695 return;
4150 4696
4151 ScopedDirLookup dir(syncdb_.manager(), syncdb_.name()); 4697 ScopedDirLookup dir(syncdb_.manager(), syncdb_.name());
(...skipping 200 matching lines...) Expand 10 before | Expand all | Expand 10 after
4352 Add(low_id_); 4898 Add(low_id_);
4353 Add(high_id_); 4899 Add(high_id_);
4354 syncer_->SyncShare(this); 4900 syncer_->SyncShare(this);
4355 ExpectLocalOrderIsByServerId(); 4901 ExpectLocalOrderIsByServerId();
4356 } 4902 }
4357 4903
4358 const SyncerTest::CommitOrderingTest 4904 const SyncerTest::CommitOrderingTest
4359 SyncerTest::CommitOrderingTest::LAST_COMMIT_ITEM = {-1, TestIdFactory::root()}; 4905 SyncerTest::CommitOrderingTest::LAST_COMMIT_ITEM = {-1, TestIdFactory::root()};
4360 4906
4361 } // namespace browser_sync 4907 } // namespace browser_sync
OLDNEW
« no previous file with comments | « chrome/browser/sync/engine/syncer_proto_util_unittest.cc ('k') | chrome/browser/sync/engine/syncer_util.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698