| OLD | NEW |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 |
| OLD | NEW |