| 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 entry. | 3 // found in the LICENSE entry. |
| 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> |
| 11 | 11 |
| 12 #include "base/at_exit.h" | 12 #include "base/at_exit.h" |
| 13 | 13 |
| 14 #include "base/scoped_ptr.h" | 14 #include "base/scoped_ptr.h" |
| 15 #include "build/build_config.h" | 15 #include "build/build_config.h" |
| 16 #include "chrome/browser/sync/engine/client_command_channel.h" | 16 #include "chrome/browser/sync/engine/client_command_channel.h" |
| 17 #include "chrome/browser/sync/engine/conflict_resolution_view.h" | 17 #include "chrome/browser/sync/engine/conflict_resolution_view.h" |
| 18 #include "chrome/browser/sync/engine/conflict_resolver.h" | 18 #include "chrome/browser/sync/engine/conflict_resolver.h" |
| 19 #include "chrome/browser/sync/engine/get_commit_ids_command.h" | 19 #include "chrome/browser/sync/engine/get_commit_ids_command.h" |
| 20 #include "chrome/browser/sync/engine/model_safe_worker.h" | 20 #include "chrome/browser/sync/engine/model_safe_worker.h" |
| 21 #include "chrome/browser/sync/engine/net/server_connection_manager.h" | 21 #include "chrome/browser/sync/engine/net/server_connection_manager.h" |
| 22 #include "chrome/browser/sync/engine/process_updates_command.h" | 22 #include "chrome/browser/sync/engine/process_updates_command.h" |
| 23 #include "chrome/browser/sync/engine/syncer.h" | 23 #include "chrome/browser/sync/engine/syncer.h" |
| 24 #include "chrome/browser/sync/engine/syncer_util.h" | 24 #include "chrome/browser/sync/engine/syncer_util.h" |
| 25 #include "chrome/browser/sync/engine/syncer_proto_util.h" | 25 #include "chrome/browser/sync/engine/syncer_proto_util.h" |
| 26 #include "chrome/browser/sync/engine/syncer_session.h" | 26 #include "chrome/browser/sync/engine/syncer_session.h" |
| 27 #include "chrome/browser/sync/protocol/sync.pb.h" | 27 #include "chrome/browser/sync/protocol/sync.pb.h" |
| 28 #include "chrome/browser/sync/syncable/directory_manager.h" | 28 #include "chrome/browser/sync/syncable/directory_manager.h" |
| 29 #include "chrome/browser/sync/syncable/syncable.h" | 29 #include "chrome/browser/sync/syncable/syncable.h" |
| 30 #include "chrome/browser/sync/util/closure.h" |
| 30 #include "chrome/browser/sync/util/event_sys-inl.h" | 31 #include "chrome/browser/sync/util/event_sys-inl.h" |
| 31 #include "chrome/test/sync/engine/mock_server_connection.h" | 32 #include "chrome/test/sync/engine/mock_server_connection.h" |
| 32 #include "chrome/test/sync/engine/test_directory_setter_upper.h" | 33 #include "chrome/test/sync/engine/test_directory_setter_upper.h" |
| 33 #include "chrome/test/sync/engine/test_id_factory.h" | 34 #include "chrome/test/sync/engine/test_id_factory.h" |
| 35 #include "chrome/test/sync/engine/test_syncable_utils.h" |
| 34 #include "testing/gtest/include/gtest/gtest.h" | 36 #include "testing/gtest/include/gtest/gtest.h" |
| 35 | 37 |
| 36 using std::map; | 38 using std::map; |
| 37 using std::multimap; | 39 using std::multimap; |
| 38 using std::set; | 40 using std::set; |
| 39 using std::string; | 41 using std::string; |
| 40 | 42 |
| 41 namespace browser_sync { | 43 namespace browser_sync { |
| 42 | 44 |
| 43 using syncable::BaseTransaction; | 45 using syncable::BaseTransaction; |
| 44 using syncable::Blob; | 46 using syncable::Blob; |
| 47 using syncable::CountEntriesWithName; |
| 45 using syncable::Directory; | 48 using syncable::Directory; |
| 46 using syncable::Entry; | 49 using syncable::Entry; |
| 47 using syncable::ExtendedAttribute; | 50 using syncable::ExtendedAttribute; |
| 48 using syncable::ExtendedAttributeKey; | 51 using syncable::ExtendedAttributeKey; |
| 52 using syncable::GetFirstEntryWithName; |
| 53 using syncable::GetOnlyEntryWithName; |
| 49 using syncable::Id; | 54 using syncable::Id; |
| 50 using syncable::MutableEntry; | 55 using syncable::MutableEntry; |
| 51 using syncable::MutableExtendedAttribute; | 56 using syncable::MutableExtendedAttribute; |
| 52 using syncable::ReadTransaction; | 57 using syncable::ReadTransaction; |
| 53 using syncable::ScopedDirLookup; | 58 using syncable::ScopedDirLookup; |
| 54 using syncable::WriteTransaction; | 59 using syncable::WriteTransaction; |
| 55 | 60 |
| 56 using syncable::BASE_VERSION; | 61 using syncable::BASE_VERSION; |
| 57 using syncable::CREATE; | 62 using syncable::CREATE; |
| 58 using syncable::CREATE_NEW_UPDATE_ITEM; | 63 using syncable::CREATE_NEW_UPDATE_ITEM; |
| 59 using syncable::GET_BY_HANDLE; | 64 using syncable::GET_BY_HANDLE; |
| 60 using syncable::GET_BY_ID; | 65 using syncable::GET_BY_ID; |
| 61 using syncable::GET_BY_PARENTID_AND_NAME; | |
| 62 using syncable::GET_BY_PATH; | |
| 63 using syncable::GET_BY_TAG; | 66 using syncable::GET_BY_TAG; |
| 64 using syncable::ID; | 67 using syncable::ID; |
| 65 using syncable::IS_BOOKMARK_OBJECT; | 68 using syncable::IS_BOOKMARK_OBJECT; |
| 66 using syncable::IS_DEL; | 69 using syncable::IS_DEL; |
| 67 using syncable::IS_DIR; | 70 using syncable::IS_DIR; |
| 68 using syncable::IS_UNAPPLIED_UPDATE; | 71 using syncable::IS_UNAPPLIED_UPDATE; |
| 69 using syncable::IS_UNSYNCED; | 72 using syncable::IS_UNSYNCED; |
| 70 using syncable::META_HANDLE; | 73 using syncable::META_HANDLE; |
| 71 using syncable::MTIME; | 74 using syncable::MTIME; |
| 72 using syncable::NAME; | |
| 73 using syncable::NEXT_ID; | 75 using syncable::NEXT_ID; |
| 76 using syncable::NON_UNIQUE_NAME; |
| 74 using syncable::PARENT_ID; | 77 using syncable::PARENT_ID; |
| 75 using syncable::PREV_ID; | 78 using syncable::PREV_ID; |
| 76 using syncable::SERVER_IS_DEL; | 79 using syncable::SERVER_IS_DEL; |
| 77 using syncable::SERVER_NAME; | 80 using syncable::SERVER_NON_UNIQUE_NAME; |
| 78 using syncable::SERVER_PARENT_ID; | 81 using syncable::SERVER_PARENT_ID; |
| 79 using syncable::SERVER_POSITION_IN_PARENT; | 82 using syncable::SERVER_POSITION_IN_PARENT; |
| 80 using syncable::SERVER_VERSION; | 83 using syncable::SERVER_VERSION; |
| 81 using syncable::SINGLETON_TAG; | 84 using syncable::SINGLETON_TAG; |
| 82 using syncable::UNITTEST; | 85 using syncable::UNITTEST; |
| 83 using syncable::UNSANITIZED_NAME; | |
| 84 | 86 |
| 85 namespace { | 87 namespace { |
| 86 const char* kTestData = "Hello World!"; | 88 const char* kTestData = "Hello World!"; |
| 87 const int kTestDataLen = 12; | 89 const int kTestDataLen = 12; |
| 88 const int64 kTestLogRequestTimestamp = 123456; | 90 const int64 kTestLogRequestTimestamp = 123456; |
| 89 } // namespace | 91 } // namespace |
| 90 | 92 |
| 91 class SyncerTest : public testing::Test { | 93 class SyncerTest : public testing::Test { |
| 92 protected: | 94 protected: |
| 93 SyncerTest() : client_command_channel_(0) { | 95 SyncerTest() : client_command_channel_(0) { |
| (...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 158 syncer_->channel(), | 160 syncer_->channel(), |
| 159 syncer_->model_safe_worker())); | 161 syncer_->model_safe_worker())); |
| 160 | 162 |
| 161 ScopedDirLookup dir(syncdb_.manager(), syncdb_.name()); | 163 ScopedDirLookup dir(syncdb_.manager(), syncdb_.name()); |
| 162 CHECK(dir.good()); | 164 CHECK(dir.good()); |
| 163 ReadTransaction trans(dir, __FILE__, __LINE__); | 165 ReadTransaction trans(dir, __FILE__, __LINE__); |
| 164 syncable::Directory::ChildHandles children; | 166 syncable::Directory::ChildHandles children; |
| 165 dir->GetChildHandles(&trans, trans.root_id(), &children); | 167 dir->GetChildHandles(&trans, trans.root_id(), &children); |
| 166 ASSERT_TRUE(0 == children.size()); | 168 ASSERT_TRUE(0 == children.size()); |
| 167 syncer_events_.clear(); | 169 syncer_events_.clear(); |
| 168 root_id_ = ids_.root(); | 170 root_id_ = TestIdFactory::root(); |
| 169 parent_id_ = ids_.MakeServer("parent id"); | 171 parent_id_ = ids_.MakeServer("parent id"); |
| 170 child_id_ = ids_.MakeServer("child id"); | 172 child_id_ = ids_.MakeServer("child id"); |
| 171 } | 173 } |
| 172 | 174 |
| 173 virtual void TearDown() { | 175 virtual void TearDown() { |
| 174 mock_server_.reset(); | 176 mock_server_.reset(); |
| 175 hookup_.reset(); | 177 hookup_.reset(); |
| 176 command_channel_hookup_.reset(); | 178 command_channel_hookup_.reset(); |
| 177 delete syncer_; | 179 delete syncer_; |
| 178 syncdb_.TearDown(); | 180 syncdb_.TearDown(); |
| (...skipping 155 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 334 EXPECT_TRUE(entry.good()); | 336 EXPECT_TRUE(entry.good()); |
| 335 entry.Put(syncable::IS_UNSYNCED, true); | 337 entry.Put(syncable::IS_UNSYNCED, true); |
| 336 entry.Put(syncable::IS_DIR, true); | 338 entry.Put(syncable::IS_DIR, true); |
| 337 entry.Put(syncable::BASE_VERSION, id.ServerKnows() ? 1 : 0); | 339 entry.Put(syncable::BASE_VERSION, id.ServerKnows() ? 1 : 0); |
| 338 entry.Put(syncable::ID, id); | 340 entry.Put(syncable::ID, id); |
| 339 return entry.Get(META_HANDLE); | 341 return entry.Get(META_HANDLE); |
| 340 } | 342 } |
| 341 | 343 |
| 342 // Some ids to aid tests. Only the root one's value is specific. The rest | 344 // Some ids to aid tests. Only the root one's value is specific. The rest |
| 343 // are named for test clarity. | 345 // are named for test clarity. |
| 346 // TODO(chron): Get rid of these inbuilt IDs. They only make it |
| 347 // more confusing. |
| 344 syncable::Id root_id_; | 348 syncable::Id root_id_; |
| 345 syncable::Id parent_id_; | 349 syncable::Id parent_id_; |
| 346 syncable::Id child_id_; | 350 syncable::Id child_id_; |
| 347 | 351 |
| 348 TestIdFactory ids_; | 352 TestIdFactory ids_; |
| 349 | 353 |
| 350 TestDirectorySetterUpper syncdb_; | 354 TestDirectorySetterUpper syncdb_; |
| 351 scoped_ptr<MockConnectionManager> mock_server_; | 355 scoped_ptr<MockConnectionManager> mock_server_; |
| 352 scoped_ptr<EventListenerHookup> hookup_; | 356 scoped_ptr<EventListenerHookup> hookup_; |
| 353 scoped_ptr<EventListenerHookup> command_channel_hookup_; | 357 scoped_ptr<EventListenerHookup> command_channel_hookup_; |
| (...skipping 454 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 808 ASSERT_TRUE(3 == mock_server_->committed_ids().size()); | 812 ASSERT_TRUE(3 == mock_server_->committed_ids().size()); |
| 809 // If this test starts failing, be aware other sort orders could be valid. | 813 // If this test starts failing, be aware other sort orders could be valid. |
| 810 EXPECT_TRUE(parent_id_ == mock_server_->committed_ids()[0]); | 814 EXPECT_TRUE(parent_id_ == mock_server_->committed_ids()[0]); |
| 811 EXPECT_TRUE(child_id_ == mock_server_->committed_ids()[1]); | 815 EXPECT_TRUE(child_id_ == mock_server_->committed_ids()[1]); |
| 812 EXPECT_TRUE(child2_id == mock_server_->committed_ids()[2]); | 816 EXPECT_TRUE(child2_id == mock_server_->committed_ids()[2]); |
| 813 } | 817 } |
| 814 | 818 |
| 815 TEST_F(SyncerTest, TestCommitListOrderingAndNewParent) { | 819 TEST_F(SyncerTest, TestCommitListOrderingAndNewParent) { |
| 816 ScopedDirLookup dir(syncdb_.manager(), syncdb_.name()); | 820 ScopedDirLookup dir(syncdb_.manager(), syncdb_.name()); |
| 817 ASSERT_TRUE(dir.good()); | 821 ASSERT_TRUE(dir.good()); |
| 822 |
| 823 PathString parent1_name = PSTR("1"); |
| 824 PathString parent2_name = PSTR("A"); |
| 825 PathString child_name = PSTR("B"); |
| 826 |
| 818 { | 827 { |
| 819 WriteTransaction wtrans(dir, UNITTEST, __FILE__, __LINE__); | 828 WriteTransaction wtrans(dir, UNITTEST, __FILE__, __LINE__); |
| 820 MutableEntry parent(&wtrans, syncable::CREATE, wtrans.root_id(), PSTR("1")); | 829 MutableEntry parent(&wtrans, syncable::CREATE, wtrans.root_id(), parent1_nam
e); |
| 821 ASSERT_TRUE(parent.good()); | 830 ASSERT_TRUE(parent.good()); |
| 822 parent.Put(syncable::IS_UNSYNCED, true); | 831 parent.Put(syncable::IS_UNSYNCED, true); |
| 823 parent.Put(syncable::IS_DIR, true); | 832 parent.Put(syncable::IS_DIR, true); |
| 824 parent.Put(syncable::ID, parent_id_); | 833 parent.Put(syncable::ID, parent_id_); |
| 825 parent.Put(syncable::BASE_VERSION, 1); | 834 parent.Put(syncable::BASE_VERSION, 1); |
| 826 } | 835 } |
| 827 | 836 |
| 828 syncable::Id parent2_id = ids_.NewLocalId(); | 837 syncable::Id parent2_id = ids_.NewLocalId(); |
| 829 syncable::Id child2_id = ids_.NewServerId(); | 838 syncable::Id child_id = ids_.NewServerId(); |
| 830 { | 839 { |
| 831 WriteTransaction wtrans(dir, UNITTEST, __FILE__, __LINE__); | 840 WriteTransaction wtrans(dir, UNITTEST, __FILE__, __LINE__); |
| 832 MutableEntry parent(&wtrans, syncable::CREATE, parent_id_, PSTR("A")); | 841 MutableEntry parent2(&wtrans, syncable::CREATE, parent_id_, parent2_name); |
| 833 ASSERT_TRUE(parent.good()); | 842 ASSERT_TRUE(parent2.good()); |
| 834 parent.Put(syncable::IS_UNSYNCED, true); | 843 parent2.Put(syncable::IS_UNSYNCED, true); |
| 835 parent.Put(syncable::IS_DIR, true); | 844 parent2.Put(syncable::IS_DIR, true); |
| 836 parent.Put(syncable::ID, parent2_id); | 845 parent2.Put(syncable::ID, parent2_id); |
| 837 MutableEntry child(&wtrans, syncable::CREATE, parent2_id, PSTR("B")); | 846 |
| 847 MutableEntry child(&wtrans, syncable::CREATE, parent2_id, child_name); |
| 838 ASSERT_TRUE(child.good()); | 848 ASSERT_TRUE(child.good()); |
| 839 child.Put(syncable::IS_UNSYNCED, true); | 849 child.Put(syncable::IS_UNSYNCED, true); |
| 840 child.Put(syncable::IS_DIR, true); | 850 child.Put(syncable::IS_DIR, true); |
| 841 child.Put(syncable::ID, child2_id); | 851 child.Put(syncable::ID, child_id); |
| 842 child.Put(syncable::BASE_VERSION, 1); | 852 child.Put(syncable::BASE_VERSION, 1); |
| 843 } | 853 } |
| 844 | 854 |
| 845 SyncCycleState cycle_state; | 855 SyncCycleState cycle_state; |
| 846 SyncerSession session(&cycle_state, state_.get()); | 856 SyncerSession session(&cycle_state, state_.get()); |
| 847 | 857 |
| 848 syncer_->SyncShare(&session); | 858 syncer_->SyncShare(&session); |
| 849 EXPECT_TRUE(3 == session.unsynced_count()); | 859 EXPECT_TRUE(3 == session.unsynced_count()); |
| 850 ASSERT_TRUE(3 == mock_server_->committed_ids().size()); | 860 ASSERT_TRUE(3 == mock_server_->committed_ids().size()); |
| 851 // If this test starts failing, be aware other sort orders could be valid. | 861 // If this test starts failing, be aware other sort orders could be valid. |
| 852 EXPECT_TRUE(parent_id_ == mock_server_->committed_ids()[0]); | 862 EXPECT_TRUE(parent_id_ == mock_server_->committed_ids()[0]); |
| 853 EXPECT_TRUE(parent2_id == mock_server_->committed_ids()[1]); | 863 EXPECT_TRUE(parent2_id == mock_server_->committed_ids()[1]); |
| 854 EXPECT_TRUE(child2_id == mock_server_->committed_ids()[2]); | 864 EXPECT_TRUE(child_id == mock_server_->committed_ids()[2]); |
| 855 { | 865 { |
| 856 ReadTransaction rtrans(dir, __FILE__, __LINE__); | 866 ReadTransaction rtrans(dir, __FILE__, __LINE__); |
| 857 PathChar path[] = { '1', *kPathSeparator, 'A', 0}; | 867 // Check that things committed correctly. |
| 858 Entry entry_1A(&rtrans, syncable::GET_BY_PATH, path); | 868 Entry entry_1(&rtrans, syncable::GET_BY_ID, parent_id_); |
| 859 ASSERT_TRUE(entry_1A.good()); | 869 EXPECT_EQ(entry_1.Get(NON_UNIQUE_NAME), parent1_name); |
| 860 Entry item_parent2(&rtrans, syncable::GET_BY_ID, parent2_id); | 870 // Check that parent2 is a subfolder of parent1. |
| 861 ASSERT_FALSE(item_parent2.good()); | 871 EXPECT_EQ(1, CountEntriesWithName(&rtrans, |
| 862 Entry item_child2(&rtrans, syncable::GET_BY_ID, child2_id); | 872 parent_id_, |
| 863 EXPECT_EQ(entry_1A.Get(syncable::ID), item_child2.Get(syncable::PARENT_ID)); | 873 parent2_name)); |
| 864 EXPECT_TRUE(entry_1A.Get(syncable::ID).ServerKnows()); | 874 |
| 875 // Parent2 was a local ID and thus should have changed on commit! |
| 876 Entry pre_commit_entry_parent2(&rtrans, syncable::GET_BY_ID, parent2_id); |
| 877 ASSERT_FALSE(pre_commit_entry_parent2.good()); |
| 878 |
| 879 // Look up the new ID. |
| 880 Id parent2_committed_id = |
| 881 GetOnlyEntryWithName(&rtrans, parent_id_, parent2_name); |
| 882 EXPECT_TRUE(parent2_committed_id.ServerKnows()); |
| 883 |
| 884 Entry child(&rtrans, syncable::GET_BY_ID, child_id); |
| 885 EXPECT_EQ(parent2_committed_id, child.Get(syncable::PARENT_ID)); |
| 865 } | 886 } |
| 866 } | 887 } |
| 867 | 888 |
| 868 TEST_F(SyncerTest, TestCommitListOrderingAndNewParentAndChild) { | 889 TEST_F(SyncerTest, TestCommitListOrderingAndNewParentAndChild) { |
| 869 ScopedDirLookup dir(syncdb_.manager(), syncdb_.name()); | 890 ScopedDirLookup dir(syncdb_.manager(), syncdb_.name()); |
| 870 ASSERT_TRUE(dir.good()); | 891 ASSERT_TRUE(dir.good()); |
| 892 |
| 893 PathString parent_name = PSTR("1"); |
| 894 PathString parent2_name = PSTR("A"); |
| 895 PathString child_name = PSTR("B"); |
| 896 |
| 871 { | 897 { |
| 872 WriteTransaction wtrans(dir, UNITTEST, __FILE__, __LINE__); | 898 WriteTransaction wtrans(dir, UNITTEST, __FILE__, __LINE__); |
| 873 MutableEntry parent(&wtrans, syncable::CREATE, wtrans.root_id(), PSTR("1")); | 899 MutableEntry parent(&wtrans, |
| 900 syncable::CREATE, |
| 901 wtrans.root_id(), |
| 902 parent_name); |
| 874 ASSERT_TRUE(parent.good()); | 903 ASSERT_TRUE(parent.good()); |
| 875 parent.Put(syncable::IS_UNSYNCED, true); | 904 parent.Put(syncable::IS_UNSYNCED, true); |
| 876 parent.Put(syncable::IS_DIR, true); | 905 parent.Put(syncable::IS_DIR, true); |
| 877 parent.Put(syncable::ID, parent_id_); | 906 parent.Put(syncable::ID, parent_id_); |
| 878 parent.Put(syncable::BASE_VERSION, 1); | 907 parent.Put(syncable::BASE_VERSION, 1); |
| 879 } | 908 } |
| 909 |
| 880 int64 meta_handle_a, meta_handle_b; | 910 int64 meta_handle_a, meta_handle_b; |
| 911 const Id parent2_local_id = ids_.NewLocalId(); |
| 912 const Id child_local_id = ids_.NewLocalId(); |
| 881 { | 913 { |
| 882 WriteTransaction wtrans(dir, UNITTEST, __FILE__, __LINE__); | 914 WriteTransaction wtrans(dir, UNITTEST, __FILE__, __LINE__); |
| 883 MutableEntry parent(&wtrans, syncable::CREATE, parent_id_, PSTR("A")); | 915 MutableEntry parent2(&wtrans, syncable::CREATE, parent_id_, parent2_name); |
| 884 ASSERT_TRUE(parent.good()); | 916 ASSERT_TRUE(parent2.good()); |
| 885 parent.Put(syncable::IS_UNSYNCED, true); | 917 parent2.Put(syncable::IS_UNSYNCED, true); |
| 886 parent.Put(syncable::IS_DIR, true); | 918 parent2.Put(syncable::IS_DIR, true); |
| 887 parent.Put(syncable::ID, ids_.FromNumber(-101)); | 919 |
| 888 meta_handle_a = parent.Get(syncable::META_HANDLE); | 920 parent2.Put(syncable::ID, parent2_local_id); |
| 889 MutableEntry child(&wtrans, syncable::CREATE, ids_.FromNumber(-101), | 921 meta_handle_a = parent2.Get(syncable::META_HANDLE); |
| 890 PSTR("B")); | 922 MutableEntry child(&wtrans, syncable::CREATE, parent2_local_id, child_name); |
| 891 ASSERT_TRUE(child.good()); | 923 ASSERT_TRUE(child.good()); |
| 892 child.Put(syncable::IS_UNSYNCED, true); | 924 child.Put(syncable::IS_UNSYNCED, true); |
| 893 child.Put(syncable::IS_DIR, true); | 925 child.Put(syncable::IS_DIR, true); |
| 894 child.Put(syncable::ID, ids_.FromNumber(-102)); | 926 child.Put(syncable::ID, child_local_id); |
| 895 meta_handle_b = child.Get(syncable::META_HANDLE); | 927 meta_handle_b = child.Get(syncable::META_HANDLE); |
| 896 } | 928 } |
| 897 | 929 |
| 898 SyncCycleState cycle_state; | 930 SyncCycleState cycle_state; |
| 899 SyncerSession session(&cycle_state, state_.get()); | 931 SyncerSession session(&cycle_state, state_.get()); |
| 900 | 932 |
| 901 syncer_->SyncShare(&session); | 933 syncer_->SyncShare(&session); |
| 902 EXPECT_TRUE(3 == session.unsynced_count()); | 934 EXPECT_TRUE(3 == session.unsynced_count()); |
| 903 ASSERT_TRUE(3 == mock_server_->committed_ids().size()); | 935 ASSERT_TRUE(3 == mock_server_->committed_ids().size()); |
| 904 // If this test starts failing, be aware other sort orders could be valid. | 936 // If this test starts failing, be aware other sort orders could be valid. |
| 905 EXPECT_TRUE(parent_id_ == mock_server_->committed_ids()[0]); | 937 EXPECT_TRUE(parent_id_ == mock_server_->committed_ids()[0]); |
| 906 EXPECT_TRUE(ids_.FromNumber(-101) == mock_server_->committed_ids()[1]); | 938 EXPECT_TRUE(parent2_local_id == mock_server_->committed_ids()[1]); |
| 907 EXPECT_TRUE(ids_.FromNumber(-102) == mock_server_->committed_ids()[2]); | 939 EXPECT_TRUE(child_local_id == mock_server_->committed_ids()[2]); |
| 908 { | 940 { |
| 909 ReadTransaction rtrans(dir, __FILE__, __LINE__); | 941 ReadTransaction rtrans(dir, __FILE__, __LINE__); |
| 910 PathChar path[] = { '1', *kPathSeparator, 'A', 0}; | 942 |
| 911 Entry entry_1A(&rtrans, syncable::GET_BY_PATH, path); | 943 Entry parent(&rtrans, syncable::GET_BY_ID, |
| 912 ASSERT_TRUE(entry_1A.good()); | 944 GetOnlyEntryWithName(&rtrans, rtrans.root_id(), parent_name)); |
| 913 Entry entry_id_minus_101(&rtrans, syncable::GET_BY_ID, | 945 ASSERT_TRUE(parent.good()); |
| 914 ids_.FromNumber(-101)); | 946 EXPECT_TRUE(parent.Get(syncable::ID).ServerKnows()); |
| 915 ASSERT_FALSE(entry_id_minus_101.good()); | 947 |
| 948 Entry parent2(&rtrans, syncable::GET_BY_ID, |
| 949 GetOnlyEntryWithName(&rtrans, parent.Get(ID), parent2_name)); |
| 950 ASSERT_TRUE(parent2.good()); |
| 951 EXPECT_TRUE(parent2.Get(syncable::ID).ServerKnows()); |
| 952 |
| 953 // Id changed on commit, so this should fail. |
| 954 Entry local_parent2_id_entry(&rtrans, |
| 955 syncable::GET_BY_ID, |
| 956 parent2_local_id); |
| 957 ASSERT_FALSE(local_parent2_id_entry.good()); |
| 958 |
| 916 Entry entry_b(&rtrans, syncable::GET_BY_HANDLE, meta_handle_b); | 959 Entry entry_b(&rtrans, syncable::GET_BY_HANDLE, meta_handle_b); |
| 917 EXPECT_TRUE(entry_1A.Get(syncable::ID) == entry_b.Get(syncable::PARENT_ID)); | 960 EXPECT_TRUE(entry_b.Get(syncable::ID).ServerKnows()); |
| 918 EXPECT_TRUE(entry_1A.Get(syncable::ID).ServerKnows()); | 961 EXPECT_TRUE(parent2.Get(syncable::ID) == entry_b.Get(syncable::PARENT_ID)); |
| 919 } | 962 } |
| 920 } | 963 } |
| 921 | 964 |
| 922 TEST_F(SyncerTest, UpdateWithZeroLengthName) { | 965 TEST_F(SyncerTest, UpdateWithZeroLengthName) { |
| 923 ScopedDirLookup dir(syncdb_.manager(), syncdb_.name()); | 966 ScopedDirLookup dir(syncdb_.manager(), syncdb_.name()); |
| 924 ASSERT_TRUE(dir.good()); | 967 ASSERT_TRUE(dir.good()); |
| 925 // One illegal update | 968 // One illegal update |
| 926 mock_server_->AddUpdateDirectory(1, 0, "", 1, 10); | 969 mock_server_->AddUpdateDirectory(1, 0, "", 1, 10); |
| 927 // And one legal one that we're going to delete. | 970 // And one legal one that we're going to delete. |
| 928 mock_server_->AddUpdateDirectory(2, 0, "FOO", 1, 10); | 971 mock_server_->AddUpdateDirectory(2, 0, "FOO", 1, 10); |
| 929 syncer_->SyncShare(); | 972 syncer_->SyncShare(); |
| 930 // Delete the legal one. The new update has a null name. | 973 // Delete the legal one. The new update has a null name. |
| 931 mock_server_->AddUpdateDirectory(2, 0, "", 2, 20); | 974 mock_server_->AddUpdateDirectory(2, 0, "", 2, 20); |
| 932 mock_server_->SetLastUpdateDeleted(); | 975 mock_server_->SetLastUpdateDeleted(); |
| 933 syncer_->SyncShare(); | 976 syncer_->SyncShare(); |
| 934 } | 977 } |
| 935 | 978 |
| 936 #if defined(OS_WIN) | 979 TEST_F(SyncerTest, DontGetStuckWithTwoSameNames) { |
| 937 TEST_F(SyncerTest, NameSanitizationWithClientRename) { | 980 // We should not get stuck here because we get |
| 938 ScopedDirLookup dir(syncdb_.manager(), syncdb_.name()); | 981 // two server updates with exactly the same name. |
| 939 ASSERT_TRUE(dir.good()); | |
| 940 mock_server_->AddUpdateDirectory(1, 0, "okay", 1, 10); | |
| 941 syncer_->SyncShare(); | |
| 942 { | |
| 943 ReadTransaction tr(dir, __FILE__, __LINE__); | |
| 944 Entry e(&tr, syncable::GET_BY_PARENTID_AND_NAME, tr.root_id(), | |
| 945 PSTR("okay")); | |
| 946 ASSERT_TRUE(e.good()); | |
| 947 } | |
| 948 mock_server_->AddUpdateDirectory(2, 0, "prn", 1, 20); | |
| 949 syncer_->SyncShare(); | |
| 950 { | |
| 951 WriteTransaction tr(dir, UNITTEST, __FILE__, __LINE__); | |
| 952 MutableEntry e(&tr, syncable::GET_BY_PARENTID_AND_NAME, tr.root_id(), | |
| 953 PSTR("prn~1")); | |
| 954 ASSERT_TRUE(e.good()); | |
| 955 e.PutName(syncable::Name(PSTR("printer"))); | |
| 956 e.Put(syncable::IS_UNSYNCED, true); | |
| 957 } | |
| 958 syncer_->SyncShare(); | |
| 959 { | |
| 960 vector<CommitMessage*>::const_reverse_iterator it = | |
| 961 mock_server_->commit_messages().rbegin(); | |
| 962 ASSERT_TRUE(mock_server_->commit_messages().rend() != it); | |
| 963 const sync_pb::SyncEntity *const *s = (*it)->entries().data(); | |
| 964 int s_len = (*it)->entries_size(); | |
| 965 ASSERT_TRUE(1 == s_len); | |
| 966 ASSERT_TRUE("printer" == (*s)[0].name()); | |
| 967 } | |
| 968 } | |
| 969 | |
| 970 TEST_F(SyncerTest, NameSanitizationWithCascade) { | |
| 971 ScopedDirLookup dir(syncdb_.manager(), syncdb_.name()); | |
| 972 ASSERT_TRUE(dir.good()); | |
| 973 mock_server_->AddUpdateDirectory(1, 0, "prn~1", 1, 10); | |
| 974 syncer_->SyncShare(); | |
| 975 { | |
| 976 ReadTransaction tr(dir, __FILE__, __LINE__); | |
| 977 Entry e(&tr, syncable::GET_BY_PARENTID_AND_NAME, tr.root_id(), | |
| 978 PSTR("prn~1")); | |
| 979 ASSERT_TRUE(e.good()); | |
| 980 } | |
| 981 mock_server_->AddUpdateDirectory(2, 0, "prn", 1, 20); | |
| 982 syncer_->SyncShare(); | |
| 983 { | |
| 984 ReadTransaction tr(dir, __FILE__, __LINE__); | |
| 985 Entry e(&tr, syncable::GET_BY_PARENTID_AND_NAME, tr.root_id(), | |
| 986 PSTR("prn~2")); | |
| 987 ASSERT_TRUE(e.good()); | |
| 988 } | |
| 989 mock_server_->AddUpdateDirectory(3, 0, "prn~2", 1, 30); | |
| 990 syncer_->SyncShare(); | |
| 991 { | |
| 992 ReadTransaction tr(dir, __FILE__, __LINE__); | |
| 993 Entry e(&tr, syncable::GET_BY_PARENTID_AND_NAME, tr.root_id(), | |
| 994 PSTR("prn~3")); | |
| 995 ASSERT_TRUE(e.good()); | |
| 996 } | |
| 997 } | |
| 998 | |
| 999 TEST_F(SyncerTest, GetStuckWithConflictingSanitizedNames) { | |
| 1000 // We should get stuck here because we get two server updates with exactly the | |
| 1001 // same name. | |
| 1002 ScopedDirLookup dir(syncdb_.manager(), syncdb_.name()); | 982 ScopedDirLookup dir(syncdb_.manager(), syncdb_.name()); |
| 1003 ASSERT_TRUE(dir.good()); | 983 ASSERT_TRUE(dir.good()); |
| 1004 mock_server_->AddUpdateDirectory(1, 0, "foo:", 1, 10); | 984 mock_server_->AddUpdateDirectory(1, 0, "foo:", 1, 10); |
| 1005 syncer_->SyncShare(); | 985 syncer_->SyncShare(); |
| 1006 mock_server_->AddUpdateDirectory(2, 0, "foo:", 1, 20); | 986 mock_server_->AddUpdateDirectory(2, 0, "foo:", 1, 20); |
| 1007 SyncRepeatedlyToTriggerStuckSignal(state_.get()); | 987 SyncRepeatedlyToTriggerStuckSignal(state_.get()); |
| 1008 EXPECT_TRUE(SyncerStuck(state_.get())); | 988 EXPECT_FALSE(SyncerStuck(state_.get())); |
| 1009 syncer_events_.clear(); | 989 syncer_events_.clear(); |
| 1010 } | 990 } |
| 1011 | 991 |
| 1012 TEST_F(SyncerTest, MergeFolderWithSanitizedNameMatches) { | |
| 1013 ScopedDirLookup dir(syncdb_.manager(), syncdb_.name()); | |
| 1014 CHECK(dir.good()); | |
| 1015 { | |
| 1016 WriteTransaction wtrans(dir, UNITTEST, __FILE__, __LINE__); | |
| 1017 MutableEntry parent(&wtrans, CREATE, wtrans.root_id(), PSTR("Folder")); | |
| 1018 ASSERT_TRUE(parent.good()); | |
| 1019 parent.Put(IS_DIR, true); | |
| 1020 parent.Put(IS_UNSYNCED, true); | |
| 1021 parent.Put(UNSANITIZED_NAME, PSTR("Folder:")); | |
| 1022 } | |
| 1023 mock_server_->AddUpdateDirectory(100, 0, "Folder:", 10, 10); | |
| 1024 syncer_->SyncShare(); | |
| 1025 { | |
| 1026 ReadTransaction trans(dir, __FILE__, __LINE__); | |
| 1027 Directory::ChildHandles children; | |
| 1028 dir->GetChildHandles(&trans, trans.root_id(), &children); | |
| 1029 EXPECT_TRUE(1 == children.size()); | |
| 1030 Directory::UnappliedUpdateMetaHandles unapplied; | |
| 1031 dir->GetUnappliedUpdateMetaHandles(&trans, &unapplied); | |
| 1032 EXPECT_TRUE(0 == unapplied.size()); | |
| 1033 syncable::Directory::UnsyncedMetaHandles unsynced; | |
| 1034 dir->GetUnsyncedMetaHandles(&trans, &unsynced); | |
| 1035 EXPECT_TRUE(0 == unsynced.size()); | |
| 1036 syncer_events_.clear(); | |
| 1037 } | |
| 1038 } | |
| 1039 | |
| 1040 // These two tests are the same as the two above, but they introduce case | |
| 1041 // changes. | |
| 1042 TEST_F(SyncerTest, GetStuckWithSanitizedNamesThatDifferOnlyByCase) { | |
| 1043 // We should get stuck here because we get two server updates with exactly the | |
| 1044 // same name. | |
| 1045 ScopedDirLookup dir(syncdb_.manager(), syncdb_.name()); | |
| 1046 ASSERT_TRUE(dir.good()); | |
| 1047 mock_server_->AddUpdateDirectory(1, 0, "FOO:", 1, 10); | |
| 1048 syncer_->SyncShare(); | |
| 1049 mock_server_->AddUpdateDirectory(2, 0, "foo:", 1, 20); | |
| 1050 SyncRepeatedlyToTriggerStuckSignal(state_.get()); | |
| 1051 EXPECT_TRUE(SyncerStuck(state_.get())); | |
| 1052 syncer_events_.clear(); | |
| 1053 } | |
| 1054 | |
| 1055 TEST_F(SyncerTest, MergeFolderWithSanitizedNameThatDiffersOnlyByCase) { | |
| 1056 ScopedDirLookup dir(syncdb_.manager(), syncdb_.name()); | |
| 1057 CHECK(dir.good()); | |
| 1058 { | |
| 1059 WriteTransaction wtrans(dir, UNITTEST, __FILE__, __LINE__); | |
| 1060 MutableEntry parent(&wtrans, CREATE, wtrans.root_id(), PSTR("FOLDER")); | |
| 1061 ASSERT_TRUE(parent.good()); | |
| 1062 parent.Put(IS_DIR, true); | |
| 1063 parent.Put(IS_UNSYNCED, true); | |
| 1064 parent.Put(UNSANITIZED_NAME, PSTR("FOLDER:")); | |
| 1065 } | |
| 1066 mock_server_->AddUpdateDirectory(100, 0, "Folder:", 10, 10); | |
| 1067 mock_server_->set_conflict_all_commits(true); | |
| 1068 syncer_->SyncShare(); | |
| 1069 syncer_->SyncShare(); | |
| 1070 syncer_->SyncShare(); // Good gracious, these tests are not so good. | |
| 1071 { | |
| 1072 ReadTransaction trans(dir, __FILE__, __LINE__); | |
| 1073 Directory::ChildHandles children; | |
| 1074 dir->GetChildHandles(&trans, trans.root_id(), &children); | |
| 1075 EXPECT_TRUE(1 == children.size()); | |
| 1076 Directory::UnappliedUpdateMetaHandles unapplied; | |
| 1077 dir->GetUnappliedUpdateMetaHandles(&trans, &unapplied); | |
| 1078 EXPECT_TRUE(0 == unapplied.size()); | |
| 1079 syncable::Directory::UnsyncedMetaHandles unsynced; | |
| 1080 dir->GetUnsyncedMetaHandles(&trans, &unsynced); | |
| 1081 EXPECT_TRUE(0 == unsynced.size()); | |
| 1082 syncer_events_.clear(); | |
| 1083 } | |
| 1084 } | |
| 1085 #else // Mac / Linux ... | |
| 1086 | |
| 1087 TEST_F(SyncerTest, NameSanitizationWithClientRename) { | |
| 1088 ScopedDirLookup dir(syncdb_.manager(), syncdb_.name()); | |
| 1089 ASSERT_TRUE(dir.good()); | |
| 1090 mock_server_->AddUpdateDirectory(1, 0, "okay", 1, 10); | |
| 1091 syncer_->SyncShare(); | |
| 1092 { | |
| 1093 ReadTransaction tr(dir, __FILE__, __LINE__); | |
| 1094 Entry e(&tr, syncable::GET_BY_PARENTID_AND_NAME, tr.root_id(), | |
| 1095 PSTR("okay")); | |
| 1096 ASSERT_TRUE(e.good()); | |
| 1097 } | |
| 1098 mock_server_->AddUpdateDirectory(2, 0, "a/b", 1, 20); | |
| 1099 syncer_->SyncShare(); | |
| 1100 { | |
| 1101 WriteTransaction tr(dir, UNITTEST, __FILE__, __LINE__); | |
| 1102 MutableEntry e(&tr, syncable::GET_BY_PARENTID_AND_NAME, tr.root_id(), | |
| 1103 PSTR("a:b")); | |
| 1104 ASSERT_TRUE(e.good()); | |
| 1105 e.PutName(syncable::Name(PSTR("ab"))); | |
| 1106 e.Put(syncable::IS_UNSYNCED, true); | |
| 1107 } | |
| 1108 syncer_->SyncShare(); | |
| 1109 { | |
| 1110 vector<CommitMessage*>::const_reverse_iterator it = | |
| 1111 mock_server_->commit_messages().rbegin(); | |
| 1112 ASSERT_TRUE(mock_server_->commit_messages().rend() != it); | |
| 1113 const sync_pb::SyncEntity *const *s = (*it)->entries().data(); | |
| 1114 int s_len = (*it)->entries_size(); | |
| 1115 ASSERT_TRUE(1 == s_len); | |
| 1116 ASSERT_TRUE("ab" == (*s)[0].name()); | |
| 1117 } | |
| 1118 } | |
| 1119 #endif | |
| 1120 | |
| 1121 namespace { | |
| 1122 void VerifyExistsWithNameInRoot(syncable::Directory* dir, | |
| 1123 const PathString& name, | |
| 1124 const string& entry, | |
| 1125 int line) { | |
| 1126 ReadTransaction tr(dir, __FILE__, __LINE__); | |
| 1127 Entry e(&tr, syncable::GET_BY_PARENTID_AND_NAME, tr.root_id(), | |
| 1128 name); | |
| 1129 EXPECT_TRUE(e.good()) << "failed on call from " << entry << ":" << line; | |
| 1130 } | |
| 1131 } // namespace | |
| 1132 | |
| 1133 TEST_F(SyncerTest, ExtendedAttributeWithNullCharacter) { | 992 TEST_F(SyncerTest, ExtendedAttributeWithNullCharacter) { |
| 1134 ScopedDirLookup dir(syncdb_.manager(), syncdb_.name()); | 993 ScopedDirLookup dir(syncdb_.manager(), syncdb_.name()); |
| 1135 ASSERT_TRUE(dir.good()); | 994 ASSERT_TRUE(dir.good()); |
| 1136 size_t xattr_count = 2; | 995 size_t xattr_count = 2; |
| 1137 PathString xattr_keys[] = { PSTR("key"), PSTR("key2") }; | 996 PathString xattr_keys[] = { PSTR("key"), PSTR("key2") }; |
| 1138 syncable::Blob xattr_values[2]; | 997 syncable::Blob xattr_values[2]; |
| 1139 const char* value[] = { "value", "val\0ue" }; | 998 const char* value[] = { "value", "val\0ue" }; |
| 1140 int value_length[] = { 5, 6 }; | 999 int value_length[] = { 5, 6 }; |
| 1141 for (size_t i = 0; i < xattr_count; i++) { | 1000 for (size_t i = 0; i < xattr_count; i++) { |
| 1142 for (int j = 0; j < value_length[i]; j++) | 1001 for (int j = 0; j < value_length[i]; j++) |
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1196 EXPECT_TRUE(entry.Get(SERVER_VERSION) == version); | 1055 EXPECT_TRUE(entry.Get(SERVER_VERSION) == version); |
| 1197 EXPECT_TRUE(entry.Get(BASE_VERSION) == version); | 1056 EXPECT_TRUE(entry.Get(BASE_VERSION) == version); |
| 1198 EXPECT_FALSE(entry.Get(IS_UNAPPLIED_UPDATE)); | 1057 EXPECT_FALSE(entry.Get(IS_UNAPPLIED_UPDATE)); |
| 1199 EXPECT_FALSE(entry.Get(IS_UNSYNCED)); | 1058 EXPECT_FALSE(entry.Get(IS_UNSYNCED)); |
| 1200 EXPECT_FALSE(entry.Get(SERVER_IS_DEL)); | 1059 EXPECT_FALSE(entry.Get(SERVER_IS_DEL)); |
| 1201 EXPECT_FALSE(entry.Get(IS_DEL)); | 1060 EXPECT_FALSE(entry.Get(IS_DEL)); |
| 1202 } | 1061 } |
| 1203 } | 1062 } |
| 1204 | 1063 |
| 1205 TEST_F(SyncerTest, IllegalAndLegalUpdates) { | 1064 TEST_F(SyncerTest, IllegalAndLegalUpdates) { |
| 1206 Id root = ids_.root(); | 1065 Id root = TestIdFactory::root(); |
| 1207 ScopedDirLookup dir(syncdb_.manager(), syncdb_.name()); | 1066 ScopedDirLookup dir(syncdb_.manager(), syncdb_.name()); |
| 1208 ASSERT_TRUE(dir.good()); | 1067 ASSERT_TRUE(dir.good()); |
| 1209 // Should apply just fine. | 1068 // Should apply just fine. |
| 1210 mock_server_->AddUpdateDirectory(1, 0, "in_root", 10, 10); | 1069 mock_server_->AddUpdateDirectory(1, 0, "in_root", 10, 10); |
| 1211 | 1070 |
| 1212 // Name clash: this is a conflict. | 1071 // Same name. But this SHOULD work. |
| 1213 mock_server_->AddUpdateDirectory(2, 0, "in_root", 10, 10); | 1072 mock_server_->AddUpdateDirectory(2, 0, "in_root", 10, 10); |
| 1214 | 1073 |
| 1215 // Unknown parent: should never be applied. "-80" is a legal server ID, | 1074 // Unknown parent: should never be applied. "-80" is a legal server ID, |
| 1216 // because any string sent by the server is a legal server ID in the sync | 1075 // because any string sent by the server is a legal server ID in the sync |
| 1217 // protocol, but it's not the ID of any item known to the client. This | 1076 // protocol, but it's not the ID of any item known to the client. This |
| 1218 // update should succeed validation, but be stuck in the unapplied state | 1077 // update should succeed validation, but be stuck in the unapplied state |
| 1219 // until an item with the server ID "-80" arrives. | 1078 // until an item with the server ID "-80" arrives. |
| 1220 mock_server_->AddUpdateDirectory(3, -80, "bad_parent", 10, 10); | 1079 mock_server_->AddUpdateDirectory(3, -80, "bad_parent", 10, 10); |
| 1221 | 1080 |
| 1222 syncer_->SyncShare(state_.get()); | 1081 syncer_->SyncShare(state_.get()); |
| 1223 | 1082 |
| 1224 ConflictResolutionView conflict_view(state_.get()); | 1083 ConflictResolutionView conflict_view(state_.get()); |
| 1225 SyncerStatus status(NULL, state_.get()); | 1084 SyncerStatus status(NULL, state_.get()); |
| 1226 // Ids 2 and 3 are expected to be in conflict now. | 1085 // Id 3 should be in conflict now. |
| 1227 EXPECT_TRUE(2 == conflict_view.conflicting_updates()); | 1086 EXPECT_TRUE(1 == conflict_view.conflicting_updates()); |
| 1228 | 1087 |
| 1229 // These entries will be used in the second set of updates. | 1088 // These entries will be used in the second set of updates. |
| 1230 mock_server_->AddUpdateDirectory(4, 0, "newer_version", 20, 10); | 1089 mock_server_->AddUpdateDirectory(4, 0, "newer_version", 20, 10); |
| 1231 mock_server_->AddUpdateDirectory(5, 0, "circular1", 10, 10); | 1090 mock_server_->AddUpdateDirectory(5, 0, "circular1", 10, 10); |
| 1232 mock_server_->AddUpdateDirectory(6, 5, "circular2", 10, 10); | 1091 mock_server_->AddUpdateDirectory(6, 5, "circular2", 10, 10); |
| 1233 mock_server_->AddUpdateDirectory(9, 3, "bad_parent_child", 10, 10); | 1092 mock_server_->AddUpdateDirectory(9, 3, "bad_parent_child", 10, 10); |
| 1234 mock_server_->AddUpdateDirectory(100, 9, "bad_parent_child2", 10, 10); | 1093 mock_server_->AddUpdateDirectory(100, 9, "bad_parent_child2", 10, 10); |
| 1235 mock_server_->AddUpdateDirectory(10, 0, "dir_to_bookmark", 10, 10); | 1094 mock_server_->AddUpdateDirectory(10, 0, "dir_to_bookmark", 10, 10); |
| 1236 | 1095 |
| 1237 syncer_->SyncShare(state_.get()); | 1096 syncer_->SyncShare(state_.get()); |
| 1238 // The three items with an unresolved parent should be unapplied (3, 9, 100). | 1097 // The three items with an unresolved parent should be unapplied (3, 9, 100). |
| 1239 // The name clash should also still be in conflict. | 1098 EXPECT_TRUE(3 == conflict_view.conflicting_updates()); |
| 1240 EXPECT_TRUE(4 == conflict_view.conflicting_updates()); | |
| 1241 { | 1099 { |
| 1242 WriteTransaction trans(dir, UNITTEST, __FILE__, __LINE__); | 1100 WriteTransaction trans(dir, UNITTEST, __FILE__, __LINE__); |
| 1101 // Even though it has the same name, it should work. |
| 1243 Entry name_clash(&trans, GET_BY_ID, ids_.FromNumber(2)); | 1102 Entry name_clash(&trans, GET_BY_ID, ids_.FromNumber(2)); |
| 1244 ASSERT_TRUE(name_clash.good()); | 1103 ASSERT_TRUE(name_clash.good()); |
| 1245 EXPECT_TRUE(name_clash.Get(IS_UNAPPLIED_UPDATE)); | 1104 EXPECT_FALSE(name_clash.Get(IS_UNAPPLIED_UPDATE)) |
| 1105 << "Duplicate name SHOULD be OK."; |
| 1246 | 1106 |
| 1247 Entry bad_parent(&trans, GET_BY_ID, ids_.FromNumber(3)); | 1107 Entry bad_parent(&trans, GET_BY_ID, ids_.FromNumber(3)); |
| 1248 ASSERT_TRUE(bad_parent.good()); | 1108 ASSERT_TRUE(bad_parent.good()); |
| 1249 EXPECT_TRUE(name_clash.Get(IS_UNAPPLIED_UPDATE)) | 1109 EXPECT_TRUE(bad_parent.Get(IS_UNAPPLIED_UPDATE)) |
| 1250 << "child of unknown parent should be in conflict"; | 1110 << "child of unknown parent should be in conflict"; |
| 1251 | 1111 |
| 1252 Entry bad_parent_child(&trans, GET_BY_ID, ids_.FromNumber(9)); | 1112 Entry bad_parent_child(&trans, GET_BY_ID, ids_.FromNumber(9)); |
| 1253 ASSERT_TRUE(bad_parent_child.good()); | 1113 ASSERT_TRUE(bad_parent_child.good()); |
| 1254 EXPECT_TRUE(bad_parent_child.Get(IS_UNAPPLIED_UPDATE)) | 1114 EXPECT_TRUE(bad_parent_child.Get(IS_UNAPPLIED_UPDATE)) |
| 1255 << "grandchild of unknown parent should be in conflict"; | 1115 << "grandchild of unknown parent should be in conflict"; |
| 1256 | 1116 |
| 1257 Entry bad_parent_child2(&trans, GET_BY_ID, ids_.FromNumber(100)); | 1117 Entry bad_parent_child2(&trans, GET_BY_ID, ids_.FromNumber(100)); |
| 1258 ASSERT_TRUE(bad_parent_child2.good()); | 1118 ASSERT_TRUE(bad_parent_child2.good()); |
| 1259 EXPECT_TRUE(bad_parent_child2.Get(IS_UNAPPLIED_UPDATE)) | 1119 EXPECT_TRUE(bad_parent_child2.Get(IS_UNAPPLIED_UPDATE)) |
| 1260 << "great-grandchild of unknown parent should be in conflict"; | 1120 << "great-grandchild of unknown parent should be in conflict"; |
| 1261 } | 1121 } |
| 1262 | 1122 |
| 1263 // Updating 1 should unblock the clashing item 2. | 1123 // Updating 1 should not affect item 2 of the same name. |
| 1264 mock_server_->AddUpdateDirectory(1, 0, "new_name", 20, 20); | 1124 mock_server_->AddUpdateDirectory(1, 0, "new_name", 20, 20); |
| 1265 | 1125 |
| 1266 // Moving 5 under 6 will create a cycle: a conflict. | 1126 // Moving 5 under 6 will create a cycle: a conflict. |
| 1267 mock_server_->AddUpdateDirectory(5, 6, "circular3", 20, 20); | 1127 mock_server_->AddUpdateDirectory(5, 6, "circular3", 20, 20); |
| 1268 | 1128 |
| 1269 // Flip the is_dir bit: should fail verify & be dropped. | 1129 // Flip the is_dir bit: should fail verify & be dropped. |
| 1270 mock_server_->AddUpdateBookmark(10, 0, "dir_to_bookmark", 20, 20); | 1130 mock_server_->AddUpdateBookmark(10, 0, "dir_to_bookmark", 20, 20); |
| 1271 syncer_->SyncShare(state_.get()); | 1131 syncer_->SyncShare(state_.get()); |
| 1272 | 1132 |
| 1273 // Version number older than last known: should fail verify & be dropped. | 1133 // Version number older than last known: should fail verify & be dropped. |
| 1274 mock_server_->AddUpdateDirectory(4, 0, "old_version", 10, 10); | 1134 mock_server_->AddUpdateDirectory(4, 0, "old_version", 10, 10); |
| 1275 syncer_->SyncShare(state_.get()); | 1135 syncer_->SyncShare(state_.get()); |
| 1276 { | 1136 { |
| 1277 ReadTransaction trans(dir, __FILE__, __LINE__); | 1137 ReadTransaction trans(dir, __FILE__, __LINE__); |
| 1138 |
| 1278 Entry still_a_dir(&trans, GET_BY_ID, ids_.FromNumber(10)); | 1139 Entry still_a_dir(&trans, GET_BY_ID, ids_.FromNumber(10)); |
| 1279 ASSERT_TRUE(still_a_dir.good()); | 1140 ASSERT_TRUE(still_a_dir.good()); |
| 1280 EXPECT_FALSE(still_a_dir.Get(IS_UNAPPLIED_UPDATE)); | 1141 EXPECT_FALSE(still_a_dir.Get(IS_UNAPPLIED_UPDATE)); |
| 1281 EXPECT_TRUE(10 == still_a_dir.Get(BASE_VERSION)); | 1142 EXPECT_TRUE(10 == still_a_dir.Get(BASE_VERSION)); |
| 1282 EXPECT_TRUE(10 == still_a_dir.Get(SERVER_VERSION)); | 1143 EXPECT_TRUE(10 == still_a_dir.Get(SERVER_VERSION)); |
| 1283 EXPECT_TRUE(still_a_dir.Get(IS_DIR)); | 1144 EXPECT_TRUE(still_a_dir.Get(IS_DIR)); |
| 1284 | 1145 |
| 1285 Entry rename(&trans, GET_BY_PARENTID_AND_NAME, root, PSTR("new_name")); | 1146 Entry rename(&trans, GET_BY_ID, ids_.FromNumber(1)); |
| 1286 ASSERT_TRUE(rename.good()); | 1147 ASSERT_TRUE(rename.good()); |
| 1148 EXPECT_EQ(root, rename.Get(PARENT_ID)); |
| 1149 EXPECT_EQ(PSTR("new_name"), rename.Get(NON_UNIQUE_NAME)); |
| 1287 EXPECT_FALSE(rename.Get(IS_UNAPPLIED_UPDATE)); | 1150 EXPECT_FALSE(rename.Get(IS_UNAPPLIED_UPDATE)); |
| 1288 EXPECT_TRUE(ids_.FromNumber(1) == rename.Get(ID)); | 1151 EXPECT_TRUE(ids_.FromNumber(1) == rename.Get(ID)); |
| 1289 EXPECT_TRUE(20 == rename.Get(BASE_VERSION)); | 1152 EXPECT_TRUE(20 == rename.Get(BASE_VERSION)); |
| 1290 | 1153 |
| 1291 Entry unblocked(&trans, GET_BY_PARENTID_AND_NAME, root, PSTR("in_root")); | 1154 Entry name_clash(&trans, GET_BY_ID, ids_.FromNumber(2)); |
| 1292 ASSERT_TRUE(unblocked.good()); | 1155 ASSERT_TRUE(name_clash.good()); |
| 1293 EXPECT_FALSE(unblocked.Get(IS_UNAPPLIED_UPDATE)); | 1156 EXPECT_EQ(root, name_clash.Get(PARENT_ID)); |
| 1294 EXPECT_TRUE(ids_.FromNumber(2) == unblocked.Get(ID)); | 1157 EXPECT_TRUE(ids_.FromNumber(2) == name_clash.Get(ID)); |
| 1295 EXPECT_TRUE(10 == unblocked.Get(BASE_VERSION)); | 1158 EXPECT_TRUE(10 == name_clash.Get(BASE_VERSION)); |
| 1159 EXPECT_EQ(PSTR("in_root"), name_clash.Get(NON_UNIQUE_NAME)); |
| 1296 | 1160 |
| 1297 Entry ignored_old_version(&trans, GET_BY_ID, ids_.FromNumber(4)); | 1161 Entry ignored_old_version(&trans, GET_BY_ID, ids_.FromNumber(4)); |
| 1298 ASSERT_TRUE(ignored_old_version.good()); | 1162 ASSERT_TRUE(ignored_old_version.good()); |
| 1299 EXPECT_TRUE(ignored_old_version.Get(NAME) == PSTR("newer_version")); | 1163 EXPECT_TRUE( |
| 1164 ignored_old_version.Get(NON_UNIQUE_NAME) == PSTR("newer_version")); |
| 1300 EXPECT_FALSE(ignored_old_version.Get(IS_UNAPPLIED_UPDATE)); | 1165 EXPECT_FALSE(ignored_old_version.Get(IS_UNAPPLIED_UPDATE)); |
| 1301 EXPECT_TRUE(20 == ignored_old_version.Get(BASE_VERSION)); | 1166 EXPECT_TRUE(20 == ignored_old_version.Get(BASE_VERSION)); |
| 1302 | 1167 |
| 1303 Entry circular_parent_issue(&trans, GET_BY_ID, ids_.FromNumber(5)); | 1168 Entry circular_parent_issue(&trans, GET_BY_ID, ids_.FromNumber(5)); |
| 1304 ASSERT_TRUE(circular_parent_issue.good()); | 1169 ASSERT_TRUE(circular_parent_issue.good()); |
| 1305 EXPECT_TRUE(circular_parent_issue.Get(IS_UNAPPLIED_UPDATE)) | 1170 EXPECT_TRUE(circular_parent_issue.Get(IS_UNAPPLIED_UPDATE)) |
| 1306 << "circular move should be in conflict"; | 1171 << "circular move should be in conflict"; |
| 1307 EXPECT_TRUE(circular_parent_issue.Get(PARENT_ID) == root_id_); | 1172 EXPECT_TRUE(circular_parent_issue.Get(PARENT_ID) == root_id_); |
| 1308 EXPECT_TRUE(circular_parent_issue.Get(SERVER_PARENT_ID) == | 1173 EXPECT_TRUE(circular_parent_issue.Get(SERVER_PARENT_ID) == |
| 1309 ids_.FromNumber(6)); | 1174 ids_.FromNumber(6)); |
| 1310 EXPECT_TRUE(10 == circular_parent_issue.Get(BASE_VERSION)); | 1175 EXPECT_TRUE(10 == circular_parent_issue.Get(BASE_VERSION)); |
| 1311 | 1176 |
| 1312 Entry circular_parent_target(&trans, GET_BY_ID, ids_.FromNumber(6)); | 1177 Entry circular_parent_target(&trans, GET_BY_ID, ids_.FromNumber(6)); |
| 1313 ASSERT_TRUE(circular_parent_target.good()); | 1178 ASSERT_TRUE(circular_parent_target.good()); |
| 1314 EXPECT_FALSE(circular_parent_target.Get(IS_UNAPPLIED_UPDATE)); | 1179 EXPECT_FALSE(circular_parent_target.Get(IS_UNAPPLIED_UPDATE)); |
| 1315 EXPECT_TRUE(circular_parent_issue.Get(ID) == | 1180 EXPECT_TRUE(circular_parent_issue.Get(ID) == |
| 1316 circular_parent_target.Get(PARENT_ID)); | 1181 circular_parent_target.Get(PARENT_ID)); |
| 1317 EXPECT_TRUE(10 == circular_parent_target.Get(BASE_VERSION)); | 1182 EXPECT_TRUE(10 == circular_parent_target.Get(BASE_VERSION)); |
| 1318 } | 1183 } |
| 1319 | 1184 |
| 1320 EXPECT_TRUE(0 == syncer_events_.size()); | 1185 EXPECT_TRUE(0 == syncer_events_.size()); |
| 1321 EXPECT_TRUE(4 == conflict_view.conflicting_updates()); | 1186 EXPECT_TRUE(4 == conflict_view.conflicting_updates()); |
| 1322 } | 1187 } |
| 1323 | 1188 |
| 1324 TEST_F(SyncerTest, CommitTimeRename) { | 1189 TEST_F(SyncerTest, CommitTimeRename) { |
| 1325 ScopedDirLookup dir(syncdb_.manager(), syncdb_.name()); | 1190 ScopedDirLookup dir(syncdb_.manager(), syncdb_.name()); |
| 1326 ASSERT_TRUE(dir.good()); | 1191 ASSERT_TRUE(dir.good()); |
| 1192 int64 metahandle_folder; |
| 1193 int64 metahandle_new_entry; |
| 1194 |
| 1327 // Create a folder and an entry. | 1195 // Create a folder and an entry. |
| 1328 { | 1196 { |
| 1329 WriteTransaction trans(dir, UNITTEST, __FILE__, __LINE__); | 1197 WriteTransaction trans(dir, UNITTEST, __FILE__, __LINE__); |
| 1330 MutableEntry parent(&trans, CREATE, root_id_, PSTR("Folder")); | 1198 MutableEntry parent(&trans, CREATE, root_id_, PSTR("Folder")); |
| 1331 ASSERT_TRUE(parent.good()); | 1199 ASSERT_TRUE(parent.good()); |
| 1332 parent.Put(IS_DIR, true); | 1200 parent.Put(IS_DIR, true); |
| 1333 parent.Put(IS_UNSYNCED, true); | 1201 parent.Put(IS_UNSYNCED, true); |
| 1202 metahandle_folder = parent.Get(META_HANDLE); |
| 1203 |
| 1334 MutableEntry entry(&trans, CREATE, parent.Get(ID), PSTR("new_entry")); | 1204 MutableEntry entry(&trans, CREATE, parent.Get(ID), PSTR("new_entry")); |
| 1335 ASSERT_TRUE(entry.good()); | 1205 ASSERT_TRUE(entry.good()); |
| 1206 metahandle_new_entry = entry.Get(META_HANDLE); |
| 1336 WriteTestDataToEntry(&trans, &entry); | 1207 WriteTestDataToEntry(&trans, &entry); |
| 1337 } | 1208 } |
| 1338 | 1209 |
| 1339 // Mix in a directory creation too for later. | 1210 // Mix in a directory creation too for later. |
| 1340 mock_server_->AddUpdateDirectory(2, 0, "dir_in_root", 10, 10); | 1211 mock_server_->AddUpdateDirectory(2, 0, "dir_in_root", 10, 10); |
| 1341 mock_server_->SetCommitTimeRename("renamed_"); | 1212 mock_server_->SetCommitTimeRename("renamed_"); |
| 1342 syncer_->SyncShare(); | 1213 syncer_->SyncShare(); |
| 1343 | 1214 |
| 1344 // Verify it was correctly renamed. | 1215 // Verify it was correctly renamed. |
| 1345 { | 1216 { |
| 1346 ReadTransaction trans(dir, __FILE__, __LINE__); | 1217 ReadTransaction trans(dir, __FILE__, __LINE__); |
| 1347 Entry entry_folder(&trans, GET_BY_PATH, PSTR("renamed_Folder")); | 1218 Entry entry_folder(&trans, GET_BY_HANDLE, metahandle_folder); |
| 1348 ASSERT_TRUE(entry_folder.good()); | 1219 ASSERT_TRUE(entry_folder.good()); |
| 1220 EXPECT_EQ(PSTR("renamed_Folder"), entry_folder.Get(NON_UNIQUE_NAME)); |
| 1349 | 1221 |
| 1350 Entry entry_new(&trans, GET_BY_PATH, | 1222 Entry entry_new(&trans, GET_BY_HANDLE, metahandle_new_entry); |
| 1351 PSTR("renamed_Folder") + PathString(kPathSeparator) | |
| 1352 + PSTR("renamed_new_entry")); | |
| 1353 ASSERT_TRUE(entry_new.good()); | 1223 ASSERT_TRUE(entry_new.good()); |
| 1224 EXPECT_EQ(entry_folder.Get(ID), entry_new.Get(PARENT_ID)); |
| 1225 EXPECT_EQ(PSTR("renamed_new_entry"), entry_new.Get(NON_UNIQUE_NAME)); |
| 1354 | 1226 |
| 1355 // And that the unrelated directory creation worked without a rename. | 1227 // And that the unrelated directory creation worked without a rename. |
| 1356 Entry new_dir(&trans, GET_BY_PATH, PSTR("dir_in_root")); | 1228 Entry new_dir(&trans, GET_BY_ID, ids_.FromNumber(2)); |
| 1357 EXPECT_TRUE(new_dir.good()); | 1229 EXPECT_TRUE(new_dir.good()); |
| 1230 EXPECT_EQ(PSTR("dir_in_root"), new_dir.Get(NON_UNIQUE_NAME)); |
| 1358 } | 1231 } |
| 1359 } | 1232 } |
| 1360 | 1233 |
| 1361 | 1234 |
| 1362 TEST_F(SyncerTest, CommitTimeRenameI18N) { | 1235 TEST_F(SyncerTest, CommitTimeRenameI18N) { |
| 1363 // This is utf-8 for the diacritized Internationalization. | 1236 // This is utf-8 for the diacritized Internationalization. |
| 1364 const char* i18nString = "\xc3\x8e\xc3\xb1\x74\xc3\xa9\x72\xc3\xb1" | 1237 const char* i18nString = "\xc3\x8e\xc3\xb1\x74\xc3\xa9\x72\xc3\xb1" |
| 1365 "\xc3\xa5\x74\xc3\xae\xc3\xb6\xc3\xb1\xc3\xa5\x6c\xc3\xae" | 1238 "\xc3\xa5\x74\xc3\xae\xc3\xb6\xc3\xb1\xc3\xa5\x6c\xc3\xae" |
| 1366 "\xc2\x9e\xc3\xa5\x74\xc3\xae\xc3\xb6\xc3\xb1"; | 1239 "\xc2\x9e\xc3\xa5\x74\xc3\xae\xc3\xb6\xc3\xb1"; |
| 1367 | 1240 |
| 1368 ScopedDirLookup dir(syncdb_.manager(), syncdb_.name()); | 1241 ScopedDirLookup dir(syncdb_.manager(), syncdb_.name()); |
| 1369 ASSERT_TRUE(dir.good()); | 1242 ASSERT_TRUE(dir.good()); |
| 1370 // Create a folder and entry. | 1243 int64 metahandle; |
| 1244 // Create a folder, expect a commit time rename. |
| 1371 { | 1245 { |
| 1372 WriteTransaction trans(dir, UNITTEST, __FILE__, __LINE__); | 1246 WriteTransaction trans(dir, UNITTEST, __FILE__, __LINE__); |
| 1373 MutableEntry parent(&trans, CREATE, root_id_, PSTR("Folder")); | 1247 MutableEntry parent(&trans, CREATE, root_id_, PSTR("Folder")); |
| 1374 ASSERT_TRUE(parent.good()); | 1248 ASSERT_TRUE(parent.good()); |
| 1375 parent.Put(IS_DIR, true); | 1249 parent.Put(IS_DIR, true); |
| 1376 parent.Put(IS_UNSYNCED, true); | 1250 parent.Put(IS_UNSYNCED, true); |
| 1377 MutableEntry entry(&trans, CREATE, parent.Get(ID), PSTR("new_entry")); | 1251 metahandle = parent.Get(META_HANDLE); |
| 1378 ASSERT_TRUE(entry.good()); | |
| 1379 WriteTestDataToEntry(&trans, &entry); | |
| 1380 } | 1252 } |
| 1381 | 1253 |
| 1382 // Mix in a directory creation too for later. | |
| 1383 mock_server_->AddUpdateDirectory(2, 0, "dir_in_root", 10, 10); | |
| 1384 mock_server_->SetCommitTimeRename(i18nString); | 1254 mock_server_->SetCommitTimeRename(i18nString); |
| 1385 syncer_->SyncShare(); | 1255 syncer_->SyncShare(); |
| 1386 | 1256 |
| 1387 // Verify it was correctly renamed. | 1257 // Verify it was correctly renamed. |
| 1388 { | 1258 { |
| 1389 ReadTransaction trans(dir, __FILE__, __LINE__); | 1259 ReadTransaction trans(dir, __FILE__, __LINE__); |
| 1390 PathString expectedFolder(i18nString); | 1260 PathString expected_folder_name(i18nString); |
| 1391 expectedFolder.append("Folder"); | 1261 expected_folder_name.append("Folder"); |
| 1392 Entry entry_folder(&trans, GET_BY_PATH, expectedFolder); | 1262 |
| 1263 |
| 1264 Entry entry_folder(&trans, GET_BY_HANDLE, metahandle); |
| 1393 ASSERT_TRUE(entry_folder.good()); | 1265 ASSERT_TRUE(entry_folder.good()); |
| 1394 PathString expected = expectedFolder + PathString(kPathSeparator); | 1266 EXPECT_EQ(expected_folder_name, entry_folder.Get(NON_UNIQUE_NAME)); |
| 1395 expected.append(i18nString); | |
| 1396 expected.append("new_entry"); | |
| 1397 | |
| 1398 Entry entry_new(&trans, GET_BY_PATH, expected); | |
| 1399 ASSERT_TRUE(entry_new.good()); | |
| 1400 | |
| 1401 // And that the unrelated directory creation worked without a rename. | |
| 1402 Entry new_dir(&trans, GET_BY_PATH, PSTR("dir_in_root")); | |
| 1403 EXPECT_TRUE(new_dir.good()); | |
| 1404 } | 1267 } |
| 1405 } | 1268 } |
| 1406 | 1269 |
| 1407 TEST_F(SyncerTest, CommitTimeRenameCollision) { | |
| 1408 ScopedDirLookup dir(syncdb_.manager(), syncdb_.name()); | |
| 1409 ASSERT_TRUE(dir.good()); | |
| 1410 // Create a folder to collide with. | |
| 1411 { | |
| 1412 WriteTransaction trans(dir, UNITTEST, __FILE__, __LINE__); | |
| 1413 MutableEntry collider(&trans, CREATE, root_id_, PSTR("renamed_Folder")); | |
| 1414 ASSERT_TRUE(collider.good()); | |
| 1415 collider.Put(IS_DIR, true); | |
| 1416 collider.Put(IS_UNSYNCED, true); | |
| 1417 } | |
| 1418 syncer_->SyncShare(); // Now we have a folder. | |
| 1419 | |
| 1420 { | |
| 1421 WriteTransaction trans(dir, UNITTEST, __FILE__, __LINE__); | |
| 1422 MutableEntry folder(&trans, CREATE, root_id_, PSTR("Folder")); | |
| 1423 ASSERT_TRUE(folder.good()); | |
| 1424 folder.Put(IS_DIR, true); | |
| 1425 folder.Put(IS_UNSYNCED, true); | |
| 1426 } | |
| 1427 | |
| 1428 mock_server_->set_next_new_id(30000); | |
| 1429 mock_server_->SetCommitTimeRename("renamed_"); | |
| 1430 syncer_->SyncShare(); // Should collide and rename aside. | |
| 1431 // This case will only occur if we got a commit time rename aside | |
| 1432 // and the server attempts to rename to an entry that we know about, but it | |
| 1433 // does not. | |
| 1434 | |
| 1435 // Verify it was correctly renamed; one of them should have a sanitized name. | |
| 1436 { | |
| 1437 ReadTransaction trans(dir, __FILE__, __LINE__); | |
| 1438 Entry collider_folder(&trans, GET_BY_PARENTID_AND_NAME, root_id_, | |
| 1439 PSTR("renamed_Folder")); | |
| 1440 EXPECT_TRUE(collider_folder.Get(UNSANITIZED_NAME) == PSTR("")); | |
| 1441 ASSERT_TRUE(collider_folder.good()); | |
| 1442 | |
| 1443 // ID is generated by next_new_id_ and server mock prepending of strings. | |
| 1444 Entry entry_folder(&trans, GET_BY_ID, | |
| 1445 syncable::Id::CreateFromServerId("mock_server:30000")); | |
| 1446 ASSERT_TRUE(entry_folder.good()); | |
| 1447 // A little arbitrary but nothing we can do about that. | |
| 1448 EXPECT_TRUE(entry_folder.Get(NAME) == PSTR("renamed_Folder~1")); | |
| 1449 EXPECT_TRUE(entry_folder.Get(UNSANITIZED_NAME) == PSTR("renamed_Folder")); | |
| 1450 } | |
| 1451 } | |
| 1452 | |
| 1453 | |
| 1454 // A commit with a lost response produces an update that has to be reunited with | 1270 // A commit with a lost response produces an update that has to be reunited with |
| 1455 // its parent. | 1271 // its parent. |
| 1456 TEST_F(SyncerTest, CommitReuniteUpdateAdjustsChildren) { | 1272 TEST_F(SyncerTest, CommitReuniteUpdateAdjustsChildren) { |
| 1457 ScopedDirLookup dir(syncdb_.manager(), syncdb_.name()); | 1273 ScopedDirLookup dir(syncdb_.manager(), syncdb_.name()); |
| 1458 ASSERT_TRUE(dir.good()); | 1274 ASSERT_TRUE(dir.good()); |
| 1275 |
| 1459 // Create a folder in the root. | 1276 // Create a folder in the root. |
| 1277 int64 metahandle_folder; |
| 1460 { | 1278 { |
| 1461 WriteTransaction trans(dir, UNITTEST, __FILE__, __LINE__); | 1279 WriteTransaction trans(dir, UNITTEST, __FILE__, __LINE__); |
| 1462 MutableEntry entry(&trans, CREATE, trans.root_id(), PSTR("new_folder")); | 1280 MutableEntry entry(&trans, CREATE, trans.root_id(), PSTR("new_folder")); |
| 1463 ASSERT_TRUE(entry.good()); | 1281 ASSERT_TRUE(entry.good()); |
| 1464 entry.Put(IS_DIR, true); | 1282 entry.Put(IS_DIR, true); |
| 1465 entry.Put(IS_UNSYNCED, true); | 1283 entry.Put(IS_UNSYNCED, true); |
| 1284 metahandle_folder = entry.Get(META_HANDLE); |
| 1466 } | 1285 } |
| 1467 | 1286 |
| 1468 // Verify it and pull the ID out of the folder. | 1287 // Verify it and pull the ID out of the folder. |
| 1469 syncable::Id folder_id; | 1288 syncable::Id folder_id; |
| 1289 int64 metahandle_entry; |
| 1470 { | 1290 { |
| 1471 ReadTransaction trans(dir, __FILE__, __LINE__); | 1291 ReadTransaction trans(dir, __FILE__, __LINE__); |
| 1472 Entry entry(&trans, GET_BY_PATH, PSTR("new_folder")); | 1292 Entry entry(&trans, GET_BY_HANDLE, metahandle_folder); |
| 1473 ASSERT_TRUE(entry.good()); | 1293 ASSERT_TRUE(entry.good()); |
| 1474 folder_id = entry.Get(ID); | 1294 folder_id = entry.Get(ID); |
| 1475 ASSERT_TRUE(!folder_id.ServerKnows()); | 1295 ASSERT_TRUE(!folder_id.ServerKnows()); |
| 1476 } | 1296 } |
| 1477 | 1297 |
| 1478 // Create an entry in the newly created folder. | 1298 // Create an entry in the newly created folder. |
| 1479 { | 1299 { |
| 1480 WriteTransaction trans(dir, UNITTEST, __FILE__, __LINE__); | 1300 WriteTransaction trans(dir, UNITTEST, __FILE__, __LINE__); |
| 1481 MutableEntry entry(&trans, CREATE, folder_id, PSTR("new_entry")); | 1301 MutableEntry entry(&trans, CREATE, folder_id, PSTR("new_entry")); |
| 1482 ASSERT_TRUE(entry.good()); | 1302 ASSERT_TRUE(entry.good()); |
| 1303 metahandle_entry = entry.Get(META_HANDLE); |
| 1483 WriteTestDataToEntry(&trans, &entry); | 1304 WriteTestDataToEntry(&trans, &entry); |
| 1484 } | 1305 } |
| 1485 | 1306 |
| 1486 // Verify it and pull the ID out of the entry. | 1307 // Verify it and pull the ID out of the entry. |
| 1487 syncable::Id entry_id; | 1308 syncable::Id entry_id; |
| 1488 { | 1309 { |
| 1489 ReadTransaction trans(dir, __FILE__, __LINE__); | 1310 ReadTransaction trans(dir, __FILE__, __LINE__); |
| 1490 Entry entry(&trans, syncable::GET_BY_PARENTID_AND_NAME, folder_id, | 1311 Entry entry(&trans, syncable::GET_BY_HANDLE, metahandle_entry); |
| 1491 PSTR("new_entry")); | |
| 1492 ASSERT_TRUE(entry.good()); | 1312 ASSERT_TRUE(entry.good()); |
| 1313 EXPECT_EQ(folder_id, entry.Get(PARENT_ID)); |
| 1314 EXPECT_EQ(PSTR("new_entry"), entry.Get(NON_UNIQUE_NAME)); |
| 1493 entry_id = entry.Get(ID); | 1315 entry_id = entry.Get(ID); |
| 1494 EXPECT_TRUE(!entry_id.ServerKnows()); | 1316 EXPECT_TRUE(!entry_id.ServerKnows()); |
| 1495 VerifyTestDataInEntry(&trans, &entry); | 1317 VerifyTestDataInEntry(&trans, &entry); |
| 1496 } | 1318 } |
| 1497 | 1319 |
| 1498 // Now, to emulate a commit response failure, we just don't commit it. | 1320 // Now, to emulate a commit response failure, we just don't commit it. |
| 1499 int64 new_version = 150; // any larger value. | 1321 int64 new_version = 150; // any larger value. |
| 1500 int64 timestamp = 20; // arbitrary value. | 1322 int64 timestamp = 20; // arbitrary value. |
| 1501 syncable::Id new_folder_id = | 1323 syncable::Id new_folder_id = |
| 1502 syncable::Id::CreateFromServerId("folder_server_id"); | 1324 syncable::Id::CreateFromServerId("folder_server_id"); |
| 1503 | 1325 |
| 1504 // the following update should cause the folder to both apply the update, as | 1326 // The following update should cause the folder to both apply the update, as |
| 1505 // well as reassociate the id. | 1327 // well as reassociate the id. |
| 1506 mock_server_->AddUpdateDirectory(new_folder_id, root_id_, | 1328 mock_server_->AddUpdateDirectory(new_folder_id, root_id_, |
| 1507 "new_folder", new_version, timestamp); | 1329 "new_folder", new_version, timestamp); |
| 1508 mock_server_->SetLastUpdateOriginatorFields( | 1330 mock_server_->SetLastUpdateOriginatorFields( |
| 1509 dir->cache_guid(), folder_id.GetServerId()); | 1331 dir->cache_guid(), folder_id.GetServerId()); |
| 1510 | 1332 |
| 1511 // We don't want it accidentally committed, just the update applied. | 1333 // We don't want it accidentally committed, just the update applied. |
| 1512 mock_server_->set_conflict_all_commits(true); | 1334 mock_server_->set_conflict_all_commits(true); |
| 1513 | 1335 |
| 1514 // Alright! Apply that update! | 1336 // Alright! Apply that update! |
| 1515 syncer_->SyncShare(); | 1337 syncer_->SyncShare(); |
| 1516 { | 1338 { |
| 1517 // The folder's ID should have been updated. | 1339 // The folder's ID should have been updated. |
| 1518 ReadTransaction trans(dir, __FILE__, __LINE__); | 1340 ReadTransaction trans(dir, __FILE__, __LINE__); |
| 1519 Entry folder(&trans, GET_BY_PATH, PSTR("new_folder")); | 1341 Entry folder(&trans, GET_BY_HANDLE, metahandle_folder); |
| 1520 ASSERT_TRUE(folder.good()); | 1342 ASSERT_TRUE(folder.good()); |
| 1343 EXPECT_EQ(PSTR("new_folder"), folder.Get(NON_UNIQUE_NAME)); |
| 1521 EXPECT_TRUE(new_version == folder.Get(BASE_VERSION)); | 1344 EXPECT_TRUE(new_version == folder.Get(BASE_VERSION)); |
| 1522 EXPECT_TRUE(new_folder_id == folder.Get(ID)); | 1345 EXPECT_TRUE(new_folder_id == folder.Get(ID)); |
| 1523 EXPECT_TRUE(folder.Get(ID).ServerKnows()); | 1346 EXPECT_TRUE(folder.Get(ID).ServerKnows()); |
| 1347 EXPECT_EQ(trans.root_id(), folder.Get(PARENT_ID)); |
| 1524 | 1348 |
| 1525 // We changed the id of the parent, old lookups should fail. | 1349 // Since it was updated, the old folder should not exist. |
| 1526 Entry bad_entry(&trans, syncable::GET_BY_PARENTID_AND_NAME, folder_id, | 1350 Entry old_dead_folder(&trans, GET_BY_ID, folder_id); |
| 1527 PSTR("new_entry")); | 1351 EXPECT_FALSE(old_dead_folder.good()); |
| 1528 EXPECT_FALSE(bad_entry.good()); | |
| 1529 | 1352 |
| 1530 // The child's parent should have changed as well. | 1353 // The child's parent should have changed. |
| 1531 Entry entry(&trans, syncable::GET_BY_PARENTID_AND_NAME, new_folder_id, | 1354 Entry entry(&trans, syncable::GET_BY_HANDLE, metahandle_entry); |
| 1532 PSTR("new_entry")); | |
| 1533 ASSERT_TRUE(entry.good()); | 1355 ASSERT_TRUE(entry.good()); |
| 1356 EXPECT_EQ(PSTR("new_entry"), entry.Get(NON_UNIQUE_NAME)); |
| 1357 EXPECT_EQ(new_folder_id, entry.Get(PARENT_ID)); |
| 1534 EXPECT_TRUE(!entry.Get(ID).ServerKnows()); | 1358 EXPECT_TRUE(!entry.Get(ID).ServerKnows()); |
| 1535 VerifyTestDataInEntry(&trans, &entry); | 1359 VerifyTestDataInEntry(&trans, &entry); |
| 1536 } | 1360 } |
| 1537 } | 1361 } |
| 1538 | 1362 |
| 1539 // A commit with a lost response produces an update that has to be reunited with | 1363 // A commit with a lost response produces an update that has to be reunited with |
| 1540 // its parent. | 1364 // its parent. |
| 1541 TEST_F(SyncerTest, CommitReuniteUpdate) { | 1365 TEST_F(SyncerTest, CommitReuniteUpdate) { |
| 1542 ScopedDirLookup dir(syncdb_.manager(), syncdb_.name()); | 1366 ScopedDirLookup dir(syncdb_.manager(), syncdb_.name()); |
| 1543 ASSERT_TRUE(dir.good()); | 1367 ASSERT_TRUE(dir.good()); |
| 1368 |
| 1544 // Create an entry in the root. | 1369 // Create an entry in the root. |
| 1370 int64 entry_metahandle; |
| 1545 { | 1371 { |
| 1546 WriteTransaction trans(dir, UNITTEST, __FILE__, __LINE__); | 1372 WriteTransaction trans(dir, UNITTEST, __FILE__, __LINE__); |
| 1547 MutableEntry entry(&trans, CREATE, trans.root_id(), PSTR("new_entry")); | 1373 MutableEntry entry(&trans, CREATE, trans.root_id(), PSTR("new_entry")); |
| 1548 ASSERT_TRUE(entry.good()); | 1374 ASSERT_TRUE(entry.good()); |
| 1375 entry_metahandle = entry.Get(META_HANDLE); |
| 1549 WriteTestDataToEntry(&trans, &entry); | 1376 WriteTestDataToEntry(&trans, &entry); |
| 1550 } | 1377 } |
| 1378 |
| 1551 // Verify it and pull the ID out. | 1379 // Verify it and pull the ID out. |
| 1552 syncable::Id entry_id; | 1380 syncable::Id entry_id; |
| 1553 { | 1381 { |
| 1554 ReadTransaction trans(dir, __FILE__, __LINE__); | 1382 ReadTransaction trans(dir, __FILE__, __LINE__); |
| 1555 Entry entry(&trans, GET_BY_PATH, PSTR("new_entry")); | 1383 |
| 1384 Entry entry(&trans, GET_BY_HANDLE, entry_metahandle); |
| 1556 ASSERT_TRUE(entry.good()); | 1385 ASSERT_TRUE(entry.good()); |
| 1557 entry_id = entry.Get(ID); | 1386 entry_id = entry.Get(ID); |
| 1558 EXPECT_TRUE(!entry_id.ServerKnows()); | 1387 EXPECT_TRUE(!entry_id.ServerKnows()); |
| 1559 VerifyTestDataInEntry(&trans, &entry); | 1388 VerifyTestDataInEntry(&trans, &entry); |
| 1560 } | 1389 } |
| 1561 | 1390 |
| 1562 // Now, to emulate a commit response failure, we just don't commit it. | 1391 // Now, to emulate a commit response failure, we just don't commit it. |
| 1563 int64 new_version = 150; // any larger value. | 1392 int64 new_version = 150; // any larger value. |
| 1564 int64 timestamp = 20; // arbitrary value. | 1393 int64 timestamp = 20; // arbitrary value. |
| 1565 syncable::Id new_entry_id = syncable::Id::CreateFromServerId("server_id"); | 1394 syncable::Id new_entry_id = syncable::Id::CreateFromServerId("server_id"); |
| 1566 | 1395 |
| 1567 // Generate an update from the server with a relevant ID reassignment. | 1396 // Generate an update from the server with a relevant ID reassignment. |
| 1568 mock_server_->AddUpdateBookmark(new_entry_id, root_id_, | 1397 mock_server_->AddUpdateBookmark(new_entry_id, root_id_, |
| 1569 "new_entry", new_version, timestamp); | 1398 "new_entry", new_version, timestamp); |
| 1570 mock_server_->SetLastUpdateOriginatorFields( | 1399 mock_server_->SetLastUpdateOriginatorFields( |
| 1571 dir->cache_guid(), entry_id.GetServerId()); | 1400 dir->cache_guid(), entry_id.GetServerId()); |
| 1572 | 1401 |
| 1573 // We don't want it accidentally committed, just the update applied. | 1402 // We don't want it accidentally committed, just the update applied. |
| 1574 mock_server_->set_conflict_all_commits(true); | 1403 mock_server_->set_conflict_all_commits(true); |
| 1575 | 1404 |
| 1576 // Alright! Apply that update! | 1405 // Alright! Apply that update! |
| 1577 syncer_->SyncShare(); | 1406 syncer_->SyncShare(); |
| 1578 { | 1407 { |
| 1579 ReadTransaction trans(dir, __FILE__, __LINE__); | 1408 ReadTransaction trans(dir, __FILE__, __LINE__); |
| 1580 Entry entry(&trans, GET_BY_PATH, PSTR("new_entry")); | 1409 Entry entry(&trans, GET_BY_HANDLE, entry_metahandle); |
| 1581 ASSERT_TRUE(entry.good()); | 1410 ASSERT_TRUE(entry.good()); |
| 1582 EXPECT_TRUE(new_version == entry.Get(BASE_VERSION)); | 1411 EXPECT_TRUE(new_version == entry.Get(BASE_VERSION)); |
| 1583 EXPECT_TRUE(new_entry_id == entry.Get(ID)); | 1412 EXPECT_TRUE(new_entry_id == entry.Get(ID)); |
| 1413 EXPECT_EQ(PSTR("new_entry"), entry.Get(NON_UNIQUE_NAME)); |
| 1584 } | 1414 } |
| 1585 } | 1415 } |
| 1586 | 1416 |
| 1587 // A commit with a lost response must work even if the local entry was deleted | 1417 // A commit with a lost response must work even if the local entry was deleted |
| 1588 // before the update is applied. We should not duplicate the local entry in | 1418 // before the update is applied. We should not duplicate the local entry in |
| 1589 // this case, but just create another one alongside. We may wish to examine | 1419 // this case, but just create another one alongside. We may wish to examine |
| 1590 // this behavior in the future as it can create hanging uploads that never | 1420 // this behavior in the future as it can create hanging uploads that never |
| 1591 // finish, that must be cleaned up on the server side after some time. | 1421 // finish, that must be cleaned up on the server side after some time. |
| 1592 TEST_F(SyncerTest, CommitReuniteUpdateDoesNotChokeOnDeletedLocalEntry) { | 1422 TEST_F(SyncerTest, CommitReuniteUpdateDoesNotChokeOnDeletedLocalEntry) { |
| 1593 ScopedDirLookup dir(syncdb_.manager(), syncdb_.name()); | 1423 ScopedDirLookup dir(syncdb_.manager(), syncdb_.name()); |
| 1594 ASSERT_TRUE(dir.good()); | 1424 ASSERT_TRUE(dir.good()); |
| 1425 |
| 1595 // Create a entry in the root. | 1426 // Create a entry in the root. |
| 1427 int64 entry_metahandle; |
| 1596 { | 1428 { |
| 1597 WriteTransaction trans(dir, UNITTEST, __FILE__, __LINE__); | 1429 WriteTransaction trans(dir, UNITTEST, __FILE__, __LINE__); |
| 1598 MutableEntry entry(&trans, CREATE, trans.root_id(), PSTR("new_entry")); | 1430 MutableEntry entry(&trans, CREATE, trans.root_id(), PSTR("new_entry")); |
| 1599 ASSERT_TRUE(entry.good()); | 1431 ASSERT_TRUE(entry.good()); |
| 1432 entry_metahandle = entry.Get(META_HANDLE); |
| 1600 WriteTestDataToEntry(&trans, &entry); | 1433 WriteTestDataToEntry(&trans, &entry); |
| 1601 } | 1434 } |
| 1602 // Verify it and pull the ID out. | 1435 // Verify it and pull the ID out. |
| 1603 syncable::Id entry_id; | 1436 syncable::Id entry_id; |
| 1604 { | 1437 { |
| 1605 ReadTransaction trans(dir, __FILE__, __LINE__); | 1438 ReadTransaction trans(dir, __FILE__, __LINE__); |
| 1606 Entry entry(&trans, GET_BY_PATH, PSTR("new_entry")); | 1439 Entry entry(&trans, GET_BY_HANDLE, entry_metahandle); |
| 1607 ASSERT_TRUE(entry.good()); | 1440 ASSERT_TRUE(entry.good()); |
| 1608 entry_id = entry.Get(ID); | 1441 entry_id = entry.Get(ID); |
| 1609 EXPECT_TRUE(!entry_id.ServerKnows()); | 1442 EXPECT_TRUE(!entry_id.ServerKnows()); |
| 1610 VerifyTestDataInEntry(&trans, &entry); | 1443 VerifyTestDataInEntry(&trans, &entry); |
| 1611 } | 1444 } |
| 1612 | 1445 |
| 1613 // Now, to emulate a commit response failure, we just don't commit it. | 1446 // Now, to emulate a commit response failure, we just don't commit it. |
| 1614 int64 new_version = 150; // any larger value. | 1447 int64 new_version = 150; // any larger value. |
| 1615 int64 timestamp = 20; // arbitrary value. | 1448 int64 timestamp = 20; // arbitrary value. |
| 1616 syncable::Id new_entry_id = syncable::Id::CreateFromServerId("server_id"); | 1449 syncable::Id new_entry_id = syncable::Id::CreateFromServerId("server_id"); |
| 1617 | 1450 |
| 1618 // Generate an update from the server with a relevant ID reassignment. | 1451 // Generate an update from the server with a relevant ID reassignment. |
| 1619 mock_server_->AddUpdateBookmark(new_entry_id, root_id_, | 1452 mock_server_->AddUpdateBookmark(new_entry_id, root_id_, |
| 1620 "new_entry", new_version, timestamp); | 1453 "new_entry", new_version, timestamp); |
| 1621 mock_server_->SetLastUpdateOriginatorFields( | 1454 mock_server_->SetLastUpdateOriginatorFields( |
| 1622 dir->cache_guid(), | 1455 dir->cache_guid(), |
| 1623 entry_id.GetServerId()); | 1456 entry_id.GetServerId()); |
| 1624 | 1457 |
| 1625 // We don't want it accidentally committed, just the update applied. | 1458 // We don't want it accidentally committed, just the update applied. |
| 1626 mock_server_->set_conflict_all_commits(true); | 1459 mock_server_->set_conflict_all_commits(true); |
| 1627 | 1460 |
| 1628 // Purposefully delete the entry now before the update application finishes. | 1461 // Purposefully delete the entry now before the update application finishes. |
| 1629 { | 1462 { |
| 1630 WriteTransaction trans(dir, UNITTEST, __FILE__, __LINE__); | 1463 WriteTransaction trans(dir, UNITTEST, __FILE__, __LINE__); |
| 1631 MutableEntry entry(&trans, GET_BY_PATH, PSTR("new_entry")); | 1464 Id new_entry_id = GetOnlyEntryWithName( |
| 1465 &trans, trans.root_id(), PSTR("new_entry")); |
| 1466 MutableEntry entry(&trans, GET_BY_ID, new_entry_id); |
| 1632 ASSERT_TRUE(entry.good()); | 1467 ASSERT_TRUE(entry.good()); |
| 1633 entry.Put(syncable::IS_DEL, true); | 1468 entry.Put(syncable::IS_DEL, true); |
| 1634 } | 1469 } |
| 1635 | 1470 |
| 1636 // Just don't CHECK fail in sync, have the update split. | 1471 // Just don't CHECK fail in sync, have the update split. |
| 1637 syncer_->SyncShare(); | 1472 syncer_->SyncShare(); |
| 1638 { | 1473 { |
| 1639 ReadTransaction trans(dir, __FILE__, __LINE__); | 1474 ReadTransaction trans(dir, __FILE__, __LINE__); |
| 1640 Entry entry(&trans, GET_BY_PATH, PSTR("new_entry")); | 1475 Id new_entry_id = GetOnlyEntryWithName( |
| 1476 &trans, trans.root_id(), PSTR("new_entry")); |
| 1477 Entry entry(&trans, GET_BY_ID, new_entry_id); |
| 1641 ASSERT_TRUE(entry.good()); | 1478 ASSERT_TRUE(entry.good()); |
| 1642 EXPECT_FALSE(entry.Get(IS_DEL)); | 1479 EXPECT_FALSE(entry.Get(IS_DEL)); |
| 1643 | 1480 |
| 1644 Entry old_entry(&trans, GET_BY_ID, entry_id); | 1481 Entry old_entry(&trans, GET_BY_ID, entry_id); |
| 1645 ASSERT_TRUE(old_entry.good()); | 1482 ASSERT_TRUE(old_entry.good()); |
| 1646 EXPECT_TRUE(old_entry.Get(IS_DEL)); | 1483 EXPECT_TRUE(old_entry.Get(IS_DEL)); |
| 1647 } | 1484 } |
| 1648 } | 1485 } |
| 1649 | 1486 |
| 1650 // TODO(chron): Add more unsanitized name tests. | 1487 // TODO(chron): Add more unsanitized name tests. |
| (...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1735 TEST_F(SyncerTest, ReverseFolderOrderingTest) { | 1572 TEST_F(SyncerTest, ReverseFolderOrderingTest) { |
| 1736 ScopedDirLookup dir(syncdb_.manager(), syncdb_.name()); | 1573 ScopedDirLookup dir(syncdb_.manager(), syncdb_.name()); |
| 1737 ASSERT_TRUE(dir.good()); | 1574 ASSERT_TRUE(dir.good()); |
| 1738 mock_server_->AddUpdateDirectory(4, 3, "ggchild", 10, 10); | 1575 mock_server_->AddUpdateDirectory(4, 3, "ggchild", 10, 10); |
| 1739 mock_server_->AddUpdateDirectory(3, 2, "gchild", 10, 10); | 1576 mock_server_->AddUpdateDirectory(3, 2, "gchild", 10, 10); |
| 1740 mock_server_->AddUpdateDirectory(5, 4, "gggchild", 10, 10); | 1577 mock_server_->AddUpdateDirectory(5, 4, "gggchild", 10, 10); |
| 1741 mock_server_->AddUpdateDirectory(2, 1, "child", 10, 10); | 1578 mock_server_->AddUpdateDirectory(2, 1, "child", 10, 10); |
| 1742 mock_server_->AddUpdateDirectory(1, 0, "parent", 10, 10); | 1579 mock_server_->AddUpdateDirectory(1, 0, "parent", 10, 10); |
| 1743 LoopSyncShare(syncer_); | 1580 LoopSyncShare(syncer_); |
| 1744 ReadTransaction trans(dir, __FILE__, __LINE__); | 1581 ReadTransaction trans(dir, __FILE__, __LINE__); |
| 1745 Entry child(&trans, syncable::GET_BY_PARENTID_AND_NAME, ids_.FromNumber(4), | 1582 |
| 1746 PSTR("gggchild")); | 1583 Id child_id = GetOnlyEntryWithName( |
| 1584 &trans, ids_.FromNumber(4), PSTR("gggchild")); |
| 1585 Entry child(&trans, GET_BY_ID, child_id); |
| 1747 ASSERT_TRUE(child.good()); | 1586 ASSERT_TRUE(child.good()); |
| 1748 } | 1587 } |
| 1749 | 1588 |
| 1750 bool CreateFolderInBob(Directory* dir) { | 1589 class EntryCreatedInNewFolderTest : public SyncerTest { |
| 1751 WriteTransaction trans(dir, UNITTEST, __FILE__, __LINE__); | 1590 public: |
| 1752 MutableEntry bob(&trans, syncable::GET_BY_PARENTID_AND_NAME, trans.root_id(), | 1591 void CreateFolderInBob() { |
| 1753 PSTR("bob")); | 1592 ScopedDirLookup dir(syncdb_.manager(), syncdb_.name()); |
| 1754 MutableEntry entry2(&trans, syncable::CREATE, bob.Get(syncable::ID), | 1593 CHECK(dir.good()); |
| 1755 PSTR("bob")); | |
| 1756 CHECK(entry2.good()); | |
| 1757 entry2.Put(syncable::IS_DIR, true); | |
| 1758 entry2.Put(syncable::IS_UNSYNCED, true); | |
| 1759 return true; | |
| 1760 } | |
| 1761 | 1594 |
| 1762 TEST_F(SyncerTest, EntryCreatedInNewFolderMidSync) { | 1595 WriteTransaction trans(dir, UNITTEST, __FILE__, __LINE__); |
| 1596 MutableEntry bob(&trans, |
| 1597 syncable::GET_BY_ID, |
| 1598 GetOnlyEntryWithName(&trans, |
| 1599 TestIdFactory::root(), |
| 1600 PSTR("bob"))); |
| 1601 CHECK(bob.good()); |
| 1602 |
| 1603 MutableEntry entry2(&trans, syncable::CREATE, bob.Get(syncable::ID), |
| 1604 PSTR("bob")); |
| 1605 CHECK(entry2.good()); |
| 1606 entry2.Put(syncable::IS_DIR, true); |
| 1607 entry2.Put(syncable::IS_UNSYNCED, true); |
| 1608 } |
| 1609 }; |
| 1610 |
| 1611 TEST_F(EntryCreatedInNewFolderTest, EntryCreatedInNewFolderMidSync) { |
| 1763 ScopedDirLookup dir(syncdb_.manager(), syncdb_.name()); | 1612 ScopedDirLookup dir(syncdb_.manager(), syncdb_.name()); |
| 1764 CHECK(dir.good()); | 1613 CHECK(dir.good()); |
| 1765 { | 1614 { |
| 1766 WriteTransaction trans(dir, UNITTEST, __FILE__, __LINE__); | 1615 WriteTransaction trans(dir, UNITTEST, __FILE__, __LINE__); |
| 1767 MutableEntry entry(&trans, syncable::CREATE, trans.root_id(), PSTR("bob")); | 1616 MutableEntry entry(&trans, syncable::CREATE, trans.root_id(), |
| 1617 PSTR("bob")); |
| 1768 ASSERT_TRUE(entry.good()); | 1618 ASSERT_TRUE(entry.good()); |
| 1769 entry.Put(syncable::IS_DIR, true); | 1619 entry.Put(syncable::IS_DIR, true); |
| 1770 entry.Put(syncable::IS_UNSYNCED, true); | 1620 entry.Put(syncable::IS_UNSYNCED, true); |
| 1771 } | 1621 } |
| 1772 mock_server_->SetMidCommitCallbackFunction(CreateFolderInBob); | 1622 |
| 1623 mock_server_->SetMidCommitCallback( |
| 1624 NewCallback<EntryCreatedInNewFolderTest>(this, |
| 1625 &EntryCreatedInNewFolderTest::CreateFolderInBob)); |
| 1773 syncer_->SyncShare(BUILD_COMMIT_REQUEST, SYNCER_END); | 1626 syncer_->SyncShare(BUILD_COMMIT_REQUEST, SYNCER_END); |
| 1774 EXPECT_TRUE(1 == mock_server_->committed_ids().size()); | 1627 EXPECT_TRUE(1 == mock_server_->committed_ids().size()); |
| 1775 { | 1628 { |
| 1776 ReadTransaction trans(dir, __FILE__, __LINE__); | 1629 ReadTransaction trans(dir, __FILE__, __LINE__); |
| 1777 PathChar path[] = {*kPathSeparator, 'b', 'o', 'b', 0}; | 1630 Entry parent_entry(&trans, syncable::GET_BY_ID, |
| 1778 Entry entry(&trans, syncable::GET_BY_PATH, path); | 1631 GetOnlyEntryWithName(&trans, TestIdFactory::root(), PSTR("bob"))); |
| 1779 ASSERT_TRUE(entry.good()); | 1632 ASSERT_TRUE(parent_entry.good()); |
| 1780 PathChar path2[] = {*kPathSeparator, 'b', 'o', 'b', | 1633 |
| 1781 *kPathSeparator, 'b', 'o', 'b', 0}; | 1634 Id child_id = |
| 1782 Entry entry2(&trans, syncable::GET_BY_PATH, path2); | 1635 GetOnlyEntryWithName(&trans, parent_entry.Get(ID), PSTR("bob")); |
| 1783 ASSERT_TRUE(entry2.good()); | 1636 Entry child(&trans, syncable::GET_BY_ID, child_id); |
| 1637 ASSERT_TRUE(child.good()); |
| 1638 EXPECT_EQ(parent_entry.Get(ID), child.Get(PARENT_ID)); |
| 1784 } | 1639 } |
| 1785 } | 1640 } |
| 1786 | 1641 |
| 1787 bool TouchFredAndGingerInRoot(Directory* dir) { | |
| 1788 WriteTransaction trans(dir, UNITTEST, __FILE__, __LINE__); | |
| 1789 MutableEntry fred(&trans, syncable::GET_BY_PARENTID_AND_NAME, trans.root_id(), | |
| 1790 PSTR("fred")); | |
| 1791 CHECK(fred.good()); | |
| 1792 // Equivalent to touching the entry. | |
| 1793 fred.Put(syncable::IS_UNSYNCED, true); | |
| 1794 fred.Put(syncable::SYNCING, false); | |
| 1795 MutableEntry ginger(&trans, syncable::GET_BY_PARENTID_AND_NAME, | |
| 1796 trans.root_id(), PSTR("ginger")); | |
| 1797 CHECK(ginger.good()); | |
| 1798 ginger.Put(syncable::IS_UNSYNCED, true); | |
| 1799 ginger.Put(syncable::SYNCING, false); | |
| 1800 return true; | |
| 1801 } | |
| 1802 | |
| 1803 TEST_F(SyncerTest, NegativeIDInUpdate) { | 1642 TEST_F(SyncerTest, NegativeIDInUpdate) { |
| 1804 ScopedDirLookup dir(syncdb_.manager(), syncdb_.name()); | 1643 ScopedDirLookup dir(syncdb_.manager(), syncdb_.name()); |
| 1805 CHECK(dir.good()); | 1644 CHECK(dir.good()); |
| 1806 mock_server_->AddUpdateBookmark(-10, 0, "bad", 40, 40); | 1645 mock_server_->AddUpdateBookmark(-10, 0, "bad", 40, 40); |
| 1807 syncer_->SyncShare(); | 1646 syncer_->SyncShare(); |
| 1808 // The negative id would make us CHECK! | 1647 // The negative id would make us CHECK! |
| 1809 } | 1648 } |
| 1810 | 1649 |
| 1811 TEST_F(SyncerTest, UnappliedUpdateOnCreatedItemItemDoesNotCrash) { | 1650 TEST_F(SyncerTest, UnappliedUpdateOnCreatedItemItemDoesNotCrash) { |
| 1812 ScopedDirLookup dir(syncdb_.manager(), syncdb_.name()); | 1651 ScopedDirLookup dir(syncdb_.manager(), syncdb_.name()); |
| 1813 CHECK(dir.good()); | 1652 CHECK(dir.good()); |
| 1653 |
| 1654 int64 metahandle_fred; |
| 1814 { | 1655 { |
| 1815 // Create an item. | 1656 // Create an item. |
| 1816 WriteTransaction trans(dir, UNITTEST, __FILE__, __LINE__); | 1657 WriteTransaction trans(dir, UNITTEST, __FILE__, __LINE__); |
| 1817 MutableEntry fred_match(&trans, CREATE, trans.root_id(), | 1658 MutableEntry fred_match(&trans, CREATE, trans.root_id(), |
| 1818 PSTR("fred_match")); | 1659 PSTR("fred_match")); |
| 1819 ASSERT_TRUE(fred_match.good()); | 1660 ASSERT_TRUE(fred_match.good()); |
| 1661 metahandle_fred = fred_match.Get(META_HANDLE); |
| 1820 WriteTestDataToEntry(&trans, &fred_match); | 1662 WriteTestDataToEntry(&trans, &fred_match); |
| 1821 } | 1663 } |
| 1822 // Commit it. | 1664 // Commit it. |
| 1823 syncer_->SyncShare(); | 1665 syncer_->SyncShare(); |
| 1824 EXPECT_TRUE(1 == mock_server_->committed_ids().size()); | 1666 EXPECT_TRUE(1 == mock_server_->committed_ids().size()); |
| 1825 mock_server_->set_conflict_all_commits(true); | 1667 mock_server_->set_conflict_all_commits(true); |
| 1826 syncable::Id fred_match_id; | 1668 syncable::Id fred_match_id; |
| 1827 { | 1669 { |
| 1828 // Now receive a change from outside. | 1670 // Now receive a change from outside. |
| 1829 WriteTransaction trans(dir, UNITTEST, __FILE__, __LINE__); | 1671 WriteTransaction trans(dir, UNITTEST, __FILE__, __LINE__); |
| 1830 MutableEntry fred_match(&trans, GET_BY_PATH, PSTR("fred_match")); | 1672 MutableEntry fred_match(&trans, GET_BY_HANDLE, metahandle_fred); |
| 1831 ASSERT_TRUE(fred_match.good()); | 1673 ASSERT_TRUE(fred_match.good()); |
| 1832 EXPECT_TRUE(fred_match.Get(ID).ServerKnows()); | 1674 EXPECT_TRUE(fred_match.Get(ID).ServerKnows()); |
| 1833 fred_match_id = fred_match.Get(ID); | 1675 fred_match_id = fred_match.Get(ID); |
| 1834 mock_server_->AddUpdateBookmark(fred_match_id, trans.root_id(), | 1676 mock_server_->AddUpdateBookmark(fred_match_id, trans.root_id(), |
| 1835 "fred_match", 40, 40); | 1677 "fred_match", 40, 40); |
| 1836 } | 1678 } |
| 1837 // Run the syncer. | 1679 // Run the syncer. |
| 1838 for (int i = 0 ; i < 30 ; ++i) { | 1680 for (int i = 0 ; i < 30 ; ++i) { |
| 1839 syncer_->SyncShare(); | 1681 syncer_->SyncShare(); |
| 1840 } | 1682 } |
| 1841 } | 1683 } |
| 1842 | 1684 |
| 1843 TEST_F(SyncerTest, NameClashWithResolverInconsistentUpdates) { | |
| 1844 // I'm unsure what the client should really do when the scenario in this old | |
| 1845 // test occurs. The set of updates we've received are not consistent. | |
| 1846 ScopedDirLookup dir(syncdb_.manager(), syncdb_.name()); | |
| 1847 CHECK(dir.good()); | |
| 1848 const char* base_name = "name_clash_with_resolver"; | |
| 1849 const char* full_name = "name_clash_with_resolver.htm"; | |
| 1850 const PathChar* base_name_p = PSTR("name_clash_with_resolver"); | |
| 1851 mock_server_->AddUpdateBookmark(1, 0, full_name, 10, 10); | |
| 1852 syncer_->SyncShare(); | |
| 1853 { | |
| 1854 WriteTransaction trans(dir, UNITTEST, __FILE__, __LINE__); | |
| 1855 MutableEntry entry(&trans, GET_BY_ID, ids_.FromNumber(1)); | |
| 1856 ASSERT_TRUE(entry.good()); | |
| 1857 WriteTestDataToEntry(&trans, &entry); | |
| 1858 } | |
| 1859 mock_server_->AddUpdateBookmark(2, 0, full_name, 10, 10); | |
| 1860 mock_server_->set_conflict_n_commits(1); | |
| 1861 syncer_->SyncShare(); | |
| 1862 mock_server_->set_conflict_n_commits(1); | |
| 1863 syncer_->SyncShare(); | |
| 1864 EXPECT_TRUE(0 == syncer_events_.size()); | |
| 1865 { | |
| 1866 ReadTransaction trans(dir, __FILE__, __LINE__); | |
| 1867 Entry id1(&trans, GET_BY_ID, ids_.FromNumber(1)); | |
| 1868 Entry id2(&trans, GET_BY_ID, ids_.FromNumber(2)); | |
| 1869 ASSERT_TRUE(id1.good()); | |
| 1870 ASSERT_TRUE(id2.good()); | |
| 1871 EXPECT_TRUE(root_id_ == id1.Get(PARENT_ID)); | |
| 1872 EXPECT_TRUE(root_id_ == id2.Get(PARENT_ID)); | |
| 1873 PathString id1name = id1.Get(NAME); | |
| 1874 | |
| 1875 EXPECT_TRUE(base_name_p == id1name.substr(0, strlen(base_name))); | |
| 1876 EXPECT_TRUE(PSTR(".htm") == id1name.substr(id1name.length() - 4)); | |
| 1877 EXPECT_LE(id1name.length(), 200ul); | |
| 1878 EXPECT_TRUE(PSTR("name_clash_with_resolver.htm") == id2.Get(NAME)); | |
| 1879 } | |
| 1880 } | |
| 1881 | |
| 1882 TEST_F(SyncerTest, NameClashWithResolver) { | |
| 1883 ScopedDirLookup dir(syncdb_.manager(), syncdb_.name()); | |
| 1884 CHECK(dir.good()); | |
| 1885 const char* base_name = "name_clash_with_resolver"; | |
| 1886 const char* full_name = "name_clash_with_resolver.htm"; | |
| 1887 const PathChar* base_name_p = PSTR("name_clash_with_resolver"); | |
| 1888 const PathChar* full_name_p = PSTR("name_clash_with_resolver.htm"); | |
| 1889 mock_server_->AddUpdateBookmark(1, 0, "fred", 10, 10); | |
| 1890 syncer_->SyncShare(); | |
| 1891 { | |
| 1892 WriteTransaction trans(dir, UNITTEST, __FILE__, __LINE__); | |
| 1893 MutableEntry entry(&trans, GET_BY_ID, ids_.FromNumber(1)); | |
| 1894 ASSERT_TRUE(entry.good()); | |
| 1895 entry.Put(NAME, full_name_p); | |
| 1896 WriteTestDataToEntry(&trans, &entry); | |
| 1897 } | |
| 1898 mock_server_->AddUpdateBookmark(2, 0, full_name, 10, 10); | |
| 1899 // We do NOT use LoopSyncShare here because of the way that | |
| 1900 // mock_server_->conflict_n_commits works. | |
| 1901 // It will only conflict the first n commits, so if we let the syncer loop, | |
| 1902 // the second commit of the update will succeed even though it shouldn't. | |
| 1903 mock_server_->set_conflict_n_commits(1); | |
| 1904 syncer_->SyncShare(state_.get()); | |
| 1905 mock_server_->set_conflict_n_commits(1); | |
| 1906 syncer_->SyncShare(state_.get()); | |
| 1907 EXPECT_TRUE(0 == syncer_events_.size()); | |
| 1908 syncer_events_.clear(); | |
| 1909 { | |
| 1910 ReadTransaction trans(dir, __FILE__, __LINE__); | |
| 1911 Entry id1(&trans, GET_BY_ID, ids_.FromNumber(1)); | |
| 1912 Entry id2(&trans, GET_BY_ID, ids_.FromNumber(2)); | |
| 1913 ASSERT_TRUE(id1.good()); | |
| 1914 ASSERT_TRUE(id2.good()); | |
| 1915 EXPECT_TRUE(root_id_ == id1.Get(PARENT_ID)); | |
| 1916 EXPECT_TRUE(root_id_ == id2.Get(PARENT_ID)); | |
| 1917 PathString id1name = id1.Get(NAME); | |
| 1918 | |
| 1919 EXPECT_TRUE(base_name_p == id1name.substr(0, strlen(base_name))); | |
| 1920 EXPECT_TRUE(PSTR(".htm") == id1name.substr(id1name.length() - 4)); | |
| 1921 EXPECT_LE(id1name.length(), 200ul); | |
| 1922 EXPECT_TRUE(full_name_p == id2.Get(NAME)); | |
| 1923 } | |
| 1924 } | |
| 1925 | |
| 1926 TEST_F(SyncerTest, VeryLongNameClashWithResolver) { | |
| 1927 ScopedDirLookup dir(syncdb_.manager(), syncdb_.name()); | |
| 1928 CHECK(dir.good()); | |
| 1929 string name; | |
| 1930 PathString name_w; | |
| 1931 name.resize(250, 'X'); | |
| 1932 name_w.resize(250, 'X'); | |
| 1933 name.append(".htm"); | |
| 1934 name_w.append(PSTR(".htm")); | |
| 1935 mock_server_->AddUpdateBookmark(1, 0, "fred", 10, 10); | |
| 1936 syncer_->SyncShare(); | |
| 1937 { | |
| 1938 WriteTransaction trans(dir, UNITTEST, __FILE__, __LINE__); | |
| 1939 MutableEntry entry(&trans, GET_BY_ID, ids_.FromNumber(1)); | |
| 1940 ASSERT_TRUE(entry.good()); | |
| 1941 entry.Put(NAME, name_w); | |
| 1942 WriteTestDataToEntry(&trans, &entry); | |
| 1943 } | |
| 1944 mock_server_->AddUpdateBookmark(2, 0, name, 10, 10); | |
| 1945 mock_server_->set_conflict_n_commits(1); | |
| 1946 // We do NOT use LoopSyncShare here because of the way that | |
| 1947 // mock_server_->conflict_n_commits works. | |
| 1948 // It will only conflict the first n commits, so if we let the syncer loop, | |
| 1949 // the second commit of the update will succeed even though it shouldn't. | |
| 1950 syncer_->SyncShare(state_.get()); | |
| 1951 mock_server_->set_conflict_n_commits(1); | |
| 1952 syncer_->SyncShare(state_.get()); | |
| 1953 EXPECT_TRUE(0 == syncer_events_.size()); | |
| 1954 { | |
| 1955 ReadTransaction trans(dir, __FILE__, __LINE__); | |
| 1956 Entry id1(&trans, GET_BY_ID, ids_.FromNumber(1)); | |
| 1957 Entry id2(&trans, GET_BY_ID, ids_.FromNumber(2)); | |
| 1958 ASSERT_TRUE(id1.good()); | |
| 1959 ASSERT_TRUE(id2.good()); | |
| 1960 EXPECT_TRUE(root_id_ == id1.Get(PARENT_ID)); | |
| 1961 EXPECT_TRUE(root_id_ == id2.Get(PARENT_ID)); | |
| 1962 PathString id1name = id1.Get(NAME); | |
| 1963 EXPECT_TRUE(PSTR(".htm") == id1name.substr(id1name.length() - 4)); | |
| 1964 EXPECT_TRUE(name_w == id2.Get(NAME)); | |
| 1965 } | |
| 1966 } | |
| 1967 | |
| 1968 TEST_F(SyncerTest, NameClashWithResolverAndDotStartedName) { | |
| 1969 ScopedDirLookup dir(syncdb_.manager(), syncdb_.name()); | |
| 1970 CHECK(dir.good()); | |
| 1971 mock_server_->AddUpdateBookmark(1, 0, ".bob.htm", 10, 10); | |
| 1972 syncer_->SyncShare(); | |
| 1973 { | |
| 1974 WriteTransaction trans(dir, UNITTEST, __FILE__, __LINE__); | |
| 1975 MutableEntry entry(&trans, GET_BY_ID, ids_.FromNumber(1)); | |
| 1976 ASSERT_TRUE(entry.good()); | |
| 1977 entry.Put(IS_UNSYNCED, true); | |
| 1978 entry.Put(NAME, PSTR(".htm")); | |
| 1979 WriteTestDataToEntry(&trans, &entry); | |
| 1980 } | |
| 1981 mock_server_->set_conflict_all_commits(true); | |
| 1982 mock_server_->AddUpdateBookmark(2, 0, ".htm", 10, 10); | |
| 1983 syncer_->SyncShare(); | |
| 1984 syncer_->SyncShare(); | |
| 1985 EXPECT_TRUE(0 == syncer_events_.size()); | |
| 1986 { | |
| 1987 ReadTransaction trans(dir, __FILE__, __LINE__); | |
| 1988 Entry id1(&trans, GET_BY_ID, ids_.FromNumber(1)); | |
| 1989 Entry id2(&trans, GET_BY_ID, ids_.FromNumber(2)); | |
| 1990 ASSERT_TRUE(id1.good()); | |
| 1991 ASSERT_TRUE(id2.good()); | |
| 1992 EXPECT_TRUE(root_id_ == id1.Get(PARENT_ID)); | |
| 1993 EXPECT_TRUE(root_id_ == id2.Get(PARENT_ID)); | |
| 1994 PathString id1name = id1.Get(NAME); | |
| 1995 EXPECT_TRUE(PSTR(".htm") == id1name.substr(0, 4)); | |
| 1996 EXPECT_TRUE(PSTR(".htm") == id2.Get(NAME)); | |
| 1997 } | |
| 1998 } | |
| 1999 | |
| 2000 TEST_F(SyncerTest, ThreeNamesClashWithResolver) { | |
| 2001 ScopedDirLookup dir(syncdb_.manager(), syncdb_.name()); | |
| 2002 CHECK(dir.good()); | |
| 2003 mock_server_->set_conflict_all_commits(true); | |
| 2004 mock_server_->AddUpdateBookmark(1, 0, "in_root.htm", 10, 10); | |
| 2005 LoopSyncShare(syncer_); | |
| 2006 { | |
| 2007 WriteTransaction trans(dir, UNITTEST, __FILE__, __LINE__); | |
| 2008 MutableEntry entry(&trans, GET_BY_ID, ids_.FromNumber(1)); | |
| 2009 ASSERT_TRUE(entry.good()); | |
| 2010 ASSERT_FALSE(entry.Get(IS_DEL)); | |
| 2011 entry.Put(IS_UNSYNCED, true); | |
| 2012 } | |
| 2013 mock_server_->AddUpdateBookmark(2, 0, "in_root.htm", 10, 10); | |
| 2014 LoopSyncShare(syncer_); | |
| 2015 LoopSyncShare(syncer_); | |
| 2016 { | |
| 2017 WriteTransaction trans(dir, UNITTEST, __FILE__, __LINE__); | |
| 2018 MutableEntry entry(&trans, GET_BY_ID, ids_.FromNumber(2)); | |
| 2019 ASSERT_TRUE(entry.good()); | |
| 2020 ASSERT_FALSE(entry.Get(IS_DEL)); | |
| 2021 entry.Put(IS_UNSYNCED, true); | |
| 2022 } | |
| 2023 mock_server_->AddUpdateBookmark(3, 0, "in_root.htm", 10, 10); | |
| 2024 LoopSyncShare(syncer_); | |
| 2025 LoopSyncShare(syncer_); | |
| 2026 { | |
| 2027 WriteTransaction trans(dir, UNITTEST, __FILE__, __LINE__); | |
| 2028 MutableEntry entry(&trans, GET_BY_ID, ids_.FromNumber(3)); | |
| 2029 ASSERT_TRUE(entry.good()); | |
| 2030 ASSERT_FALSE(entry.Get(IS_DEL)); | |
| 2031 entry.Put(IS_UNSYNCED, true); | |
| 2032 } | |
| 2033 mock_server_->AddUpdateBookmark(4, 0, "in_root.htm", 10, 10); | |
| 2034 LoopSyncShare(syncer_); | |
| 2035 LoopSyncShare(syncer_); | |
| 2036 EXPECT_TRUE(0 == syncer_events_.size()); | |
| 2037 { | |
| 2038 ReadTransaction trans(dir, __FILE__, __LINE__); | |
| 2039 Entry id1(&trans, GET_BY_ID, ids_.FromNumber(1)); | |
| 2040 Entry id2(&trans, GET_BY_ID, ids_.FromNumber(2)); | |
| 2041 Entry id3(&trans, GET_BY_ID, ids_.FromNumber(3)); | |
| 2042 Entry id4(&trans, GET_BY_ID, ids_.FromNumber(4)); | |
| 2043 ASSERT_TRUE(id1.good()); | |
| 2044 ASSERT_TRUE(id2.good()); | |
| 2045 ASSERT_TRUE(id3.good()); | |
| 2046 ASSERT_TRUE(id4.good()); | |
| 2047 EXPECT_TRUE(root_id_ == id1.Get(PARENT_ID)); | |
| 2048 EXPECT_TRUE(root_id_ == id2.Get(PARENT_ID)); | |
| 2049 EXPECT_TRUE(root_id_ == id3.Get(PARENT_ID)); | |
| 2050 EXPECT_TRUE(root_id_ == id4.Get(PARENT_ID)); | |
| 2051 PathString id1name = id1.Get(NAME); | |
| 2052 ASSERT_GE(id1name.length(), 4ul); | |
| 2053 EXPECT_TRUE(PSTR("in_root") == id1name.substr(0, 7)); | |
| 2054 EXPECT_TRUE(PSTR(".htm") == id1name.substr(id1name.length() - 4)); | |
| 2055 EXPECT_NE(PSTR("in_root.htm"), id1.Get(NAME)); | |
| 2056 PathString id2name = id2.Get(NAME); | |
| 2057 ASSERT_GE(id2name.length(), 4ul); | |
| 2058 EXPECT_TRUE(PSTR("in_root") == id2name.substr(0, 7)); | |
| 2059 EXPECT_TRUE(PSTR(".htm") == id2name.substr(id2name.length() - 4)); | |
| 2060 EXPECT_NE(PSTR("in_root.htm"), id2.Get(NAME)); | |
| 2061 PathString id3name = id3.Get(NAME); | |
| 2062 ASSERT_GE(id3name.length(), 4ul); | |
| 2063 EXPECT_TRUE(PSTR("in_root") == id3name.substr(0, 7)); | |
| 2064 EXPECT_TRUE(PSTR(".htm") == id3name.substr(id3name.length() - 4)); | |
| 2065 EXPECT_NE(PSTR("in_root.htm"), id3.Get(NAME)); | |
| 2066 EXPECT_TRUE(PSTR("in_root.htm") == id4.Get(NAME)); | |
| 2067 } | |
| 2068 } | |
| 2069 | |
| 2070 /** | 1685 /** |
| 2071 * In the event that we have a double changed entry, that is changed on both | 1686 * In the event that we have a double changed entry, that is changed on both |
| 2072 * the client and the server, the conflict resolver should just drop one of | 1687 * the client and the server, the conflict resolver should just drop one of |
| 2073 * them and accept the other. | 1688 * them and accept the other. |
| 2074 */ | 1689 */ |
| 2075 TEST_F(SyncerTest, DoublyChangedWithResolver) { | 1690 TEST_F(SyncerTest, DoublyChangedWithResolver) { |
| 2076 ScopedDirLookup dir(syncdb_.manager(), syncdb_.name()); | 1691 ScopedDirLookup dir(syncdb_.manager(), syncdb_.name()); |
| 2077 CHECK(dir.good()); | 1692 CHECK(dir.good()); |
| 2078 { | 1693 { |
| 2079 WriteTransaction wtrans(dir, UNITTEST, __FILE__, __LINE__); | 1694 WriteTransaction wtrans(dir, UNITTEST, __FILE__, __LINE__); |
| (...skipping 20 matching lines...) Expand all Loading... |
| 2100 ASSERT_TRUE(child.good()); | 1715 ASSERT_TRUE(child.good()); |
| 2101 EXPECT_TRUE(child.Get(syncable::IS_UNSYNCED)); | 1716 EXPECT_TRUE(child.Get(syncable::IS_UNSYNCED)); |
| 2102 EXPECT_FALSE(child.Get(syncable::IS_UNAPPLIED_UPDATE)); | 1717 EXPECT_FALSE(child.Get(syncable::IS_UNAPPLIED_UPDATE)); |
| 2103 } | 1718 } |
| 2104 | 1719 |
| 2105 // Only one entry, since we just overwrite one. | 1720 // Only one entry, since we just overwrite one. |
| 2106 EXPECT_TRUE(1 == children.size()); | 1721 EXPECT_TRUE(1 == children.size()); |
| 2107 syncer_events_.clear(); | 1722 syncer_events_.clear(); |
| 2108 } | 1723 } |
| 2109 | 1724 |
| 2110 // We got this repro case when someone was editing entries while sync was | 1725 // We got this repro case when someone was editing bookmarks while sync was |
| 2111 // occuring. The entry had changed out underneath the user. | 1726 // occuring. The entry had changed out underneath the user. |
| 2112 TEST_F(SyncerTest, CommitsUpdateDoesntAlterEntry) { | 1727 TEST_F(SyncerTest, CommitsUpdateDoesntAlterEntry) { |
| 2113 ScopedDirLookup dir(syncdb_.manager(), syncdb_.name()); | 1728 ScopedDirLookup dir(syncdb_.manager(), syncdb_.name()); |
| 2114 CHECK(dir.good()); | 1729 CHECK(dir.good()); |
| 2115 int64 test_time = 123456; | 1730 int64 test_time = 123456; |
| 1731 int64 entry_metahandle; |
| 2116 { | 1732 { |
| 2117 WriteTransaction wtrans(dir, UNITTEST, __FILE__, __LINE__); | 1733 WriteTransaction wtrans(dir, UNITTEST, __FILE__, __LINE__); |
| 2118 MutableEntry entry(&wtrans, syncable::CREATE, root_id_, PSTR("Pete")); | 1734 MutableEntry entry(&wtrans, syncable::CREATE, root_id_, PSTR("Pete")); |
| 2119 ASSERT_TRUE(entry.good()); | 1735 ASSERT_TRUE(entry.good()); |
| 2120 EXPECT_FALSE(entry.Get(ID).ServerKnows()); | 1736 EXPECT_FALSE(entry.Get(ID).ServerKnows()); |
| 2121 entry.Put(syncable::IS_DIR, true); | 1737 entry.Put(syncable::IS_DIR, true); |
| 2122 entry.Put(syncable::IS_UNSYNCED, true); | 1738 entry.Put(syncable::IS_UNSYNCED, true); |
| 2123 entry.Put(syncable::MTIME, test_time); | 1739 entry.Put(syncable::MTIME, test_time); |
| 1740 entry_metahandle = entry.Get(META_HANDLE); |
| 2124 } | 1741 } |
| 2125 syncer_->SyncShare(); | 1742 syncer_->SyncShare(); |
| 2126 syncable::Id id; | 1743 syncable::Id id; |
| 2127 int64 version; | 1744 int64 version; |
| 2128 int64 server_position_in_parent; | 1745 int64 server_position_in_parent; |
| 2129 { | 1746 { |
| 2130 ReadTransaction trans(dir, __FILE__, __LINE__); | 1747 ReadTransaction trans(dir, __FILE__, __LINE__); |
| 2131 Entry entry(&trans, syncable::GET_BY_PARENTID_AND_NAME, trans.root_id(), | 1748 Entry entry(&trans, syncable::GET_BY_HANDLE, entry_metahandle); |
| 2132 PSTR("Pete")); | |
| 2133 ASSERT_TRUE(entry.good()); | 1749 ASSERT_TRUE(entry.good()); |
| 2134 id = entry.Get(ID); | 1750 id = entry.Get(ID); |
| 2135 EXPECT_TRUE(id.ServerKnows()); | 1751 EXPECT_TRUE(id.ServerKnows()); |
| 2136 version = entry.Get(BASE_VERSION); | 1752 version = entry.Get(BASE_VERSION); |
| 2137 server_position_in_parent = entry.Get(SERVER_POSITION_IN_PARENT); | 1753 server_position_in_parent = entry.Get(SERVER_POSITION_IN_PARENT); |
| 2138 } | 1754 } |
| 2139 mock_server_->AddUpdateDirectory(id, root_id_, "Pete", version, 10); | 1755 mock_server_->AddUpdateDirectory(id, root_id_, "Pete", version, 10); |
| 2140 mock_server_->SetLastUpdatePosition(server_position_in_parent); | 1756 mock_server_->SetLastUpdatePosition(server_position_in_parent); |
| 2141 syncer_->SyncShare(); | 1757 syncer_->SyncShare(); |
| 2142 { | 1758 { |
| 2143 ReadTransaction trans(dir, __FILE__, __LINE__); | 1759 ReadTransaction trans(dir, __FILE__, __LINE__); |
| 2144 Entry entry(&trans, syncable::GET_BY_ID, id); | 1760 Entry entry(&trans, syncable::GET_BY_ID, id); |
| 2145 ASSERT_TRUE(entry.good()); | 1761 ASSERT_TRUE(entry.good()); |
| 2146 EXPECT_TRUE(entry.Get(MTIME) == test_time); | 1762 EXPECT_TRUE(entry.Get(MTIME) == test_time); |
| 2147 } | 1763 } |
| 2148 } | 1764 } |
| 2149 | 1765 |
| 2150 TEST_F(SyncerTest, ParentAndChildBothMatch) { | 1766 TEST_F(SyncerTest, ParentAndChildBothMatch) { |
| 2151 ScopedDirLookup dir(syncdb_.manager(), syncdb_.name()); | 1767 ScopedDirLookup dir(syncdb_.manager(), syncdb_.name()); |
| 2152 CHECK(dir.good()); | 1768 CHECK(dir.good()); |
| 1769 syncable::Id parent_id = ids_.NewServerId(); |
| 1770 syncable::Id child_id = ids_.NewServerId(); |
| 1771 |
| 2153 { | 1772 { |
| 2154 WriteTransaction wtrans(dir, UNITTEST, __FILE__, __LINE__); | 1773 WriteTransaction wtrans(dir, UNITTEST, __FILE__, __LINE__); |
| 2155 MutableEntry parent(&wtrans, CREATE, root_id_, PSTR("Folder")); | 1774 MutableEntry parent(&wtrans, CREATE, root_id_, PSTR("Folder")); |
| 2156 ASSERT_TRUE(parent.good()); | 1775 ASSERT_TRUE(parent.good()); |
| 2157 parent.Put(IS_DIR, true); | 1776 parent.Put(IS_DIR, true); |
| 2158 parent.Put(IS_UNSYNCED, true); | 1777 parent.Put(IS_UNSYNCED, true); |
| 1778 parent.Put(ID, parent_id); |
| 1779 parent.Put(BASE_VERSION, 1); |
| 1780 parent.Put(IS_BOOKMARK_OBJECT, true); |
| 1781 |
| 2159 MutableEntry child(&wtrans, CREATE, parent.Get(ID), PSTR("test.htm")); | 1782 MutableEntry child(&wtrans, CREATE, parent.Get(ID), PSTR("test.htm")); |
| 2160 ASSERT_TRUE(child.good()); | 1783 ASSERT_TRUE(child.good()); |
| 1784 child.Put(ID, child_id); |
| 1785 child.Put(BASE_VERSION, 1); |
| 1786 child.Put(IS_BOOKMARK_OBJECT, true); |
| 2161 WriteTestDataToEntry(&wtrans, &child); | 1787 WriteTestDataToEntry(&wtrans, &child); |
| 2162 } | 1788 } |
| 2163 mock_server_->AddUpdateDirectory(parent_id_, root_id_, "Folder", 10, 10); | 1789 mock_server_->AddUpdateDirectory(parent_id, root_id_, "Folder", 10, 10); |
| 2164 mock_server_->AddUpdateBookmark(child_id_, parent_id_, "test.htm", 10, 10); | 1790 mock_server_->AddUpdateBookmark(child_id, parent_id, "test.htm", 10, 10); |
| 2165 mock_server_->set_conflict_all_commits(true); | 1791 mock_server_->set_conflict_all_commits(true); |
| 2166 syncer_->SyncShare(); | 1792 syncer_->SyncShare(); |
| 2167 syncer_->SyncShare(); | 1793 syncer_->SyncShare(); |
| 2168 syncer_->SyncShare(); | 1794 syncer_->SyncShare(); |
| 2169 { | 1795 { |
| 2170 ReadTransaction trans(dir, __FILE__, __LINE__); | 1796 ReadTransaction trans(dir, __FILE__, __LINE__); |
| 2171 Directory::ChildHandles children; | 1797 Directory::ChildHandles children; |
| 2172 dir->GetChildHandles(&trans, root_id_, &children); | 1798 dir->GetChildHandles(&trans, root_id_, &children); |
| 2173 EXPECT_TRUE(1 == children.size()); | 1799 EXPECT_TRUE(1 == children.size()); |
| 2174 dir->GetChildHandles(&trans, parent_id_, &children); | 1800 dir->GetChildHandles(&trans, parent_id, &children); |
| 2175 EXPECT_TRUE(1 == children.size()); | 1801 EXPECT_TRUE(1 == children.size()); |
| 2176 Directory::UnappliedUpdateMetaHandles unapplied; | 1802 Directory::UnappliedUpdateMetaHandles unapplied; |
| 2177 dir->GetUnappliedUpdateMetaHandles(&trans, &unapplied); | 1803 dir->GetUnappliedUpdateMetaHandles(&trans, &unapplied); |
| 2178 EXPECT_TRUE(0 == unapplied.size()); | 1804 EXPECT_TRUE(0 == unapplied.size()); |
| 2179 syncable::Directory::UnsyncedMetaHandles unsynced; | 1805 syncable::Directory::UnsyncedMetaHandles unsynced; |
| 2180 dir->GetUnsyncedMetaHandles(&trans, &unsynced); | 1806 dir->GetUnsyncedMetaHandles(&trans, &unsynced); |
| 2181 EXPECT_TRUE(0 == unsynced.size()); | 1807 EXPECT_TRUE(0 == unsynced.size()); |
| 2182 syncer_events_.clear(); | 1808 syncer_events_.clear(); |
| 2183 } | 1809 } |
| 2184 } | 1810 } |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2234 // wait for sync | 1860 // wait for sync |
| 2235 // make a new folder fred | 1861 // make a new folder fred |
| 2236 // move bob into fred | 1862 // move bob into fred |
| 2237 // remove bob | 1863 // remove bob |
| 2238 // remove fred | 1864 // remove fred |
| 2239 // if no syncing occured midway, bob will have an illegal parent | 1865 // if no syncing occured midway, bob will have an illegal parent |
| 2240 TEST_F(SyncerTest, DeletingEntryInFolder) { | 1866 TEST_F(SyncerTest, DeletingEntryInFolder) { |
| 2241 // This test is a little fake. | 1867 // This test is a little fake. |
| 2242 ScopedDirLookup dir(syncdb_.manager(), syncdb_.name()); | 1868 ScopedDirLookup dir(syncdb_.manager(), syncdb_.name()); |
| 2243 CHECK(dir.good()); | 1869 CHECK(dir.good()); |
| 1870 |
| 1871 int64 existing_metahandle; |
| 2244 { | 1872 { |
| 2245 WriteTransaction trans(dir, UNITTEST, __FILE__, __LINE__); | 1873 WriteTransaction trans(dir, UNITTEST, __FILE__, __LINE__); |
| 2246 MutableEntry entry(&trans, CREATE, trans.root_id(), PSTR("existing")); | 1874 MutableEntry entry(&trans, CREATE, trans.root_id(), PSTR("existing")); |
| 2247 ASSERT_TRUE(entry.good()); | 1875 ASSERT_TRUE(entry.good()); |
| 2248 entry.Put(IS_DIR, true); | 1876 entry.Put(IS_DIR, true); |
| 2249 entry.Put(IS_UNSYNCED, true); | 1877 entry.Put(IS_UNSYNCED, true); |
| 1878 existing_metahandle = entry.Get(META_HANDLE); |
| 2250 } | 1879 } |
| 2251 syncer_->SyncShare(state_.get()); | 1880 syncer_->SyncShare(state_.get()); |
| 2252 { | 1881 { |
| 2253 WriteTransaction trans(dir, UNITTEST, __FILE__, __LINE__); | 1882 WriteTransaction trans(dir, UNITTEST, __FILE__, __LINE__); |
| 2254 MutableEntry newfolder(&trans, CREATE, trans.root_id(), PSTR("new")); | 1883 MutableEntry newfolder(&trans, CREATE, trans.root_id(), PSTR("new")); |
| 2255 ASSERT_TRUE(newfolder.good()); | 1884 ASSERT_TRUE(newfolder.good()); |
| 2256 newfolder.Put(IS_DIR, true); | 1885 newfolder.Put(IS_DIR, true); |
| 2257 newfolder.Put(IS_UNSYNCED, true); | 1886 newfolder.Put(IS_UNSYNCED, true); |
| 2258 | 1887 |
| 2259 MutableEntry existing(&trans, GET_BY_PATH, PSTR("existing")); | 1888 MutableEntry existing(&trans, GET_BY_HANDLE, existing_metahandle); |
| 2260 ASSERT_TRUE(existing.good()); | 1889 ASSERT_TRUE(existing.good()); |
| 2261 existing.Put(PARENT_ID, newfolder.Get(ID)); | 1890 existing.Put(PARENT_ID, newfolder.Get(ID)); |
| 2262 existing.Put(IS_UNSYNCED, true); | 1891 existing.Put(IS_UNSYNCED, true); |
| 2263 EXPECT_TRUE(existing.Get(ID).ServerKnows()); | 1892 EXPECT_TRUE(existing.Get(ID).ServerKnows()); |
| 2264 | 1893 |
| 2265 newfolder.Put(IS_DEL, true); | 1894 newfolder.Put(IS_DEL, true); |
| 2266 existing.Put(IS_DEL, true); | 1895 existing.Put(IS_DEL, true); |
| 2267 } | 1896 } |
| 2268 syncer_->SyncShare(state_.get()); | 1897 syncer_->SyncShare(state_.get()); |
| 2269 SyncerStatus status(NULL, state_.get()); | 1898 SyncerStatus status(NULL, state_.get()); |
| 2270 EXPECT_TRUE(0 == status.conflicting_commits()); | 1899 EXPECT_TRUE(0 == status.conflicting_commits()); |
| 2271 } | 1900 } |
| 2272 | 1901 |
| 2273 // TODO(sync): Is this test useful anymore? | |
| 2274 TEST_F(SyncerTest, DeletingEntryWithLocalEdits) { | 1902 TEST_F(SyncerTest, DeletingEntryWithLocalEdits) { |
| 2275 ScopedDirLookup dir(syncdb_.manager(), syncdb_.name()); | 1903 ScopedDirLookup dir(syncdb_.manager(), syncdb_.name()); |
| 2276 CHECK(dir.good()); | 1904 CHECK(dir.good()); |
| 1905 int64 newfolder_metahandle; |
| 1906 |
| 2277 mock_server_->AddUpdateDirectory(1, 0, "bob", 1, 10); | 1907 mock_server_->AddUpdateDirectory(1, 0, "bob", 1, 10); |
| 2278 syncer_->SyncShare(); | 1908 syncer_->SyncShare(); |
| 2279 { | 1909 { |
| 2280 WriteTransaction trans(dir, UNITTEST, __FILE__, __LINE__); | 1910 WriteTransaction trans(dir, UNITTEST, __FILE__, __LINE__); |
| 2281 MutableEntry newfolder(&trans, CREATE, ids_.FromNumber(1), PSTR("local")); | 1911 MutableEntry newfolder(&trans, CREATE, ids_.FromNumber(1), PSTR("local")); |
| 2282 ASSERT_TRUE(newfolder.good()); | 1912 ASSERT_TRUE(newfolder.good()); |
| 2283 newfolder.Put(IS_UNSYNCED, true); | 1913 newfolder.Put(IS_UNSYNCED, true); |
| 1914 newfolder_metahandle = newfolder.Get(META_HANDLE); |
| 2284 } | 1915 } |
| 2285 mock_server_->AddUpdateDirectory(1, 0, "bob", 2, 20); | 1916 mock_server_->AddUpdateDirectory(1, 0, "bob", 2, 20); |
| 2286 mock_server_->SetLastUpdateDeleted(); | 1917 mock_server_->SetLastUpdateDeleted(); |
| 2287 syncer_->SyncShare(SYNCER_BEGIN, APPLY_UPDATES); | 1918 syncer_->SyncShare(SYNCER_BEGIN, APPLY_UPDATES); |
| 2288 { | 1919 { |
| 2289 ReadTransaction trans(dir, __FILE__, __LINE__); | 1920 ReadTransaction trans(dir, __FILE__, __LINE__); |
| 2290 Entry entry_by_path(&trans, syncable::GET_BY_PATH, | 1921 Entry entry(&trans, syncable::GET_BY_HANDLE, newfolder_metahandle); |
| 2291 PathString(PSTR("bob")) + kPathSeparator + PSTR("local")); | 1922 ASSERT_TRUE(entry.good()); |
| 2292 ASSERT_TRUE(entry_by_path.good()); | |
| 2293 } | 1923 } |
| 2294 } | 1924 } |
| 2295 | 1925 |
| 2296 TEST_F(SyncerTest, FolderSwapUpdate) { | 1926 TEST_F(SyncerTest, FolderSwapUpdate) { |
| 2297 ScopedDirLookup dir(syncdb_.manager(), syncdb_.name()); | 1927 ScopedDirLookup dir(syncdb_.manager(), syncdb_.name()); |
| 2298 CHECK(dir.good()); | 1928 CHECK(dir.good()); |
| 2299 mock_server_->AddUpdateDirectory(7801, 0, "bob", 1, 10); | 1929 mock_server_->AddUpdateDirectory(7801, 0, "bob", 1, 10); |
| 2300 mock_server_->AddUpdateDirectory(1024, 0, "fred", 1, 10); | 1930 mock_server_->AddUpdateDirectory(1024, 0, "fred", 1, 10); |
| 2301 syncer_->SyncShare(); | 1931 syncer_->SyncShare(); |
| 2302 mock_server_->AddUpdateDirectory(1024, 0, "bob", 2, 20); | 1932 mock_server_->AddUpdateDirectory(1024, 0, "bob", 2, 20); |
| 2303 mock_server_->AddUpdateDirectory(7801, 0, "fred", 2, 20); | 1933 mock_server_->AddUpdateDirectory(7801, 0, "fred", 2, 20); |
| 2304 syncer_->SyncShare(); | 1934 syncer_->SyncShare(); |
| 2305 { | 1935 { |
| 2306 ReadTransaction trans(dir, __FILE__, __LINE__); | 1936 ReadTransaction trans(dir, __FILE__, __LINE__); |
| 2307 Entry id1(&trans, GET_BY_ID, ids_.FromNumber(7801)); | 1937 Entry id1(&trans, GET_BY_ID, ids_.FromNumber(7801)); |
| 2308 ASSERT_TRUE(id1.good()); | 1938 ASSERT_TRUE(id1.good()); |
| 2309 EXPECT_TRUE(PSTR("fred") == id1.Get(NAME)); | 1939 EXPECT_TRUE(PSTR("fred") == id1.Get(NON_UNIQUE_NAME)); |
| 2310 EXPECT_TRUE(root_id_ == id1.Get(PARENT_ID)); | 1940 EXPECT_TRUE(root_id_ == id1.Get(PARENT_ID)); |
| 2311 Entry id2(&trans, GET_BY_ID, ids_.FromNumber(1024)); | 1941 Entry id2(&trans, GET_BY_ID, ids_.FromNumber(1024)); |
| 2312 ASSERT_TRUE(id2.good()); | 1942 ASSERT_TRUE(id2.good()); |
| 2313 EXPECT_TRUE(PSTR("bob") == id2.Get(NAME)); | 1943 EXPECT_TRUE(PSTR("bob") == id2.Get(NON_UNIQUE_NAME)); |
| 2314 EXPECT_TRUE(root_id_ == id2.Get(PARENT_ID)); | 1944 EXPECT_TRUE(root_id_ == id2.Get(PARENT_ID)); |
| 2315 } | 1945 } |
| 2316 syncer_events_.clear(); | 1946 syncer_events_.clear(); |
| 2317 } | 1947 } |
| 2318 | 1948 |
| 2319 TEST_F(SyncerTest, CorruptUpdateBadFolderSwapUpdate) { | 1949 TEST_F(SyncerTest, NameCollidingFolderSwapWorksFine) { |
| 2320 ScopedDirLookup dir(syncdb_.manager(), syncdb_.name()); | 1950 ScopedDirLookup dir(syncdb_.manager(), syncdb_.name()); |
| 2321 CHECK(dir.good()); | 1951 CHECK(dir.good()); |
| 2322 mock_server_->AddUpdateDirectory(7801, 0, "bob", 1, 10); | 1952 mock_server_->AddUpdateDirectory(7801, 0, "bob", 1, 10); |
| 2323 mock_server_->AddUpdateDirectory(1024, 0, "fred", 1, 10); | 1953 mock_server_->AddUpdateDirectory(1024, 0, "fred", 1, 10); |
| 2324 mock_server_->AddUpdateDirectory(4096, 0, "alice", 1, 10); | 1954 mock_server_->AddUpdateDirectory(4096, 0, "alice", 1, 10); |
| 2325 syncer_->SyncShare(); | 1955 syncer_->SyncShare(); |
| 2326 { | 1956 { |
| 2327 ReadTransaction trans(dir, __FILE__, __LINE__); | 1957 ReadTransaction trans(dir, __FILE__, __LINE__); |
| 2328 Entry id1(&trans, GET_BY_ID, ids_.FromNumber(7801)); | 1958 Entry id1(&trans, GET_BY_ID, ids_.FromNumber(7801)); |
| 2329 ASSERT_TRUE(id1.good()); | 1959 ASSERT_TRUE(id1.good()); |
| 2330 EXPECT_TRUE(PSTR("bob") == id1.Get(NAME)); | 1960 EXPECT_TRUE(PSTR("bob") == id1.Get(NON_UNIQUE_NAME)); |
| 2331 EXPECT_TRUE(root_id_ == id1.Get(PARENT_ID)); | 1961 EXPECT_TRUE(root_id_ == id1.Get(PARENT_ID)); |
| 2332 Entry id2(&trans, GET_BY_ID, ids_.FromNumber(1024)); | 1962 Entry id2(&trans, GET_BY_ID, ids_.FromNumber(1024)); |
| 2333 ASSERT_TRUE(id2.good()); | 1963 ASSERT_TRUE(id2.good()); |
| 2334 EXPECT_TRUE(PSTR("fred") == id2.Get(NAME)); | 1964 EXPECT_TRUE(PSTR("fred") == id2.Get(NON_UNIQUE_NAME)); |
| 2335 EXPECT_TRUE(root_id_ == id2.Get(PARENT_ID)); | 1965 EXPECT_TRUE(root_id_ == id2.Get(PARENT_ID)); |
| 2336 Entry id3(&trans, GET_BY_ID, ids_.FromNumber(4096)); | 1966 Entry id3(&trans, GET_BY_ID, ids_.FromNumber(4096)); |
| 2337 ASSERT_TRUE(id3.good()); | 1967 ASSERT_TRUE(id3.good()); |
| 2338 EXPECT_TRUE(PSTR("alice") == id3.Get(NAME)); | 1968 EXPECT_TRUE(PSTR("alice") == id3.Get(NON_UNIQUE_NAME)); |
| 2339 EXPECT_TRUE(root_id_ == id3.Get(PARENT_ID)); | 1969 EXPECT_TRUE(root_id_ == id3.Get(PARENT_ID)); |
| 2340 } | 1970 } |
| 2341 mock_server_->AddUpdateDirectory(1024, 0, "bob", 2, 20); | 1971 mock_server_->AddUpdateDirectory(1024, 0, "bob", 2, 20); |
| 2342 mock_server_->AddUpdateDirectory(7801, 0, "fred", 2, 20); | 1972 mock_server_->AddUpdateDirectory(7801, 0, "fred", 2, 20); |
| 2343 mock_server_->AddUpdateDirectory(4096, 0, "bob", 2, 20); | 1973 mock_server_->AddUpdateDirectory(4096, 0, "bob", 2, 20); |
| 2344 syncer_->SyncShare(); | 1974 syncer_->SyncShare(); |
| 2345 { | 1975 { |
| 2346 ReadTransaction trans(dir, __FILE__, __LINE__); | 1976 ReadTransaction trans(dir, __FILE__, __LINE__); |
| 2347 Entry id1(&trans, GET_BY_ID, ids_.FromNumber(7801)); | 1977 Entry id1(&trans, GET_BY_ID, ids_.FromNumber(7801)); |
| 2348 ASSERT_TRUE(id1.good()); | 1978 ASSERT_TRUE(id1.good()); |
| 2349 EXPECT_TRUE(PSTR("bob") == id1.Get(NAME)); | 1979 EXPECT_TRUE(PSTR("fred") == id1.Get(NON_UNIQUE_NAME)); |
| 2350 EXPECT_TRUE(root_id_ == id1.Get(PARENT_ID)); | 1980 EXPECT_TRUE(root_id_ == id1.Get(PARENT_ID)); |
| 2351 Entry id2(&trans, GET_BY_ID, ids_.FromNumber(1024)); | 1981 Entry id2(&trans, GET_BY_ID, ids_.FromNumber(1024)); |
| 2352 ASSERT_TRUE(id2.good()); | 1982 ASSERT_TRUE(id2.good()); |
| 2353 EXPECT_TRUE(PSTR("fred") == id2.Get(NAME)); | 1983 EXPECT_TRUE(PSTR("bob") == id2.Get(NON_UNIQUE_NAME)); |
| 2354 EXPECT_TRUE(root_id_ == id2.Get(PARENT_ID)); | 1984 EXPECT_TRUE(root_id_ == id2.Get(PARENT_ID)); |
| 2355 Entry id3(&trans, GET_BY_ID, ids_.FromNumber(4096)); | 1985 Entry id3(&trans, GET_BY_ID, ids_.FromNumber(4096)); |
| 2356 ASSERT_TRUE(id3.good()); | 1986 ASSERT_TRUE(id3.good()); |
| 2357 EXPECT_TRUE(PSTR("alice") == id3.Get(NAME)); | 1987 EXPECT_TRUE(PSTR("bob") == id3.Get(NON_UNIQUE_NAME)); |
| 2358 EXPECT_TRUE(root_id_ == id3.Get(PARENT_ID)); | 1988 EXPECT_TRUE(root_id_ == id3.Get(PARENT_ID)); |
| 2359 } | 1989 } |
| 2360 syncer_events_.clear(); | 1990 syncer_events_.clear(); |
| 2361 } | 1991 } |
| 2362 | 1992 |
| 2363 // TODO(chron): New set of folder swap commit tests that don't rely on | |
| 2364 // transactional commits. | |
| 2365 TEST_F(SyncerTest, DISABLED_FolderSwapCommit) { | |
| 2366 ScopedDirLookup dir(syncdb_.manager(), syncdb_.name()); | |
| 2367 CHECK(dir.good()); | |
| 2368 mock_server_->AddUpdateDirectory(7801, 0, "bob", 1, 10); | |
| 2369 mock_server_->AddUpdateDirectory(1024, 0, "fred", 1, 10); | |
| 2370 syncer_->SyncShare(); | |
| 2371 { | |
| 2372 WriteTransaction trans(dir, UNITTEST, __FILE__, __LINE__); | |
| 2373 MutableEntry id1(&trans, GET_BY_ID, ids_.FromNumber(7801)); | |
| 2374 MutableEntry id2(&trans, GET_BY_ID, ids_.FromNumber(1024)); | |
| 2375 ASSERT_TRUE(id1.good()); | |
| 2376 ASSERT_TRUE(id2.good()); | |
| 2377 EXPECT_FALSE(id1.Put(NAME, PSTR("fred"))); | |
| 2378 EXPECT_TRUE(id1.Put(NAME, PSTR("temp"))); | |
| 2379 EXPECT_TRUE(id2.Put(NAME, PSTR("bob"))); | |
| 2380 EXPECT_TRUE(id1.Put(NAME, PSTR("fred"))); | |
| 2381 id1.Put(IS_UNSYNCED, true); | |
| 2382 id2.Put(IS_UNSYNCED, true); | |
| 2383 } | |
| 2384 mock_server_->set_conflict_all_commits(true); | |
| 2385 syncer_->SyncShare(); | |
| 2386 ASSERT_TRUE(2 == mock_server_->commit_messages().size()); | |
| 2387 { | |
| 2388 ReadTransaction trans(dir, __FILE__, __LINE__); | |
| 2389 Entry id1(&trans, GET_BY_ID, ids_.FromNumber(7801)); | |
| 2390 ASSERT_TRUE(id1.good()); | |
| 2391 EXPECT_TRUE(PSTR("fred") == id1.Get(NAME)); | |
| 2392 EXPECT_TRUE(root_id_ == id1.Get(PARENT_ID)); | |
| 2393 EXPECT_FALSE(id1.Get(IS_UNSYNCED)); | |
| 2394 Entry id2(&trans, GET_BY_ID, ids_.FromNumber(1024)); | |
| 2395 ASSERT_TRUE(id2.good()); | |
| 2396 EXPECT_TRUE(PSTR("bob") == id2.Get(NAME)); | |
| 2397 EXPECT_TRUE(root_id_ == id2.Get(PARENT_ID)); | |
| 2398 EXPECT_FALSE(id2.Get(IS_UNSYNCED)); | |
| 2399 } | |
| 2400 syncer_events_.clear(); | |
| 2401 } | |
| 2402 | |
| 2403 // TODO(chron): New set of folder swap commit tests that don't rely on | |
| 2404 // transactional commits. | |
| 2405 TEST_F(SyncerTest, DISABLED_DualFolderSwapCommit) { | |
| 2406 ScopedDirLookup dir(syncdb_.manager(), syncdb_.name()); | |
| 2407 CHECK(dir.good()); | |
| 2408 mock_server_->AddUpdateDirectory(1, 0, "bob", 1, 10); | |
| 2409 mock_server_->AddUpdateDirectory(2, 0, "fred", 1, 10); | |
| 2410 mock_server_->AddUpdateDirectory(3, 0, "sue", 1, 10); | |
| 2411 mock_server_->AddUpdateDirectory(4, 0, "greg", 1, 10); | |
| 2412 syncer_->SyncShare(); | |
| 2413 { | |
| 2414 WriteTransaction trans(dir, UNITTEST, __FILE__, __LINE__); | |
| 2415 MutableEntry id1(&trans, GET_BY_ID, ids_.FromNumber(1)); | |
| 2416 MutableEntry id2(&trans, GET_BY_ID, ids_.FromNumber(2)); | |
| 2417 MutableEntry id3(&trans, GET_BY_ID, ids_.FromNumber(3)); | |
| 2418 MutableEntry id4(&trans, GET_BY_ID, ids_.FromNumber(4)); | |
| 2419 ASSERT_TRUE(id1.good()); | |
| 2420 ASSERT_TRUE(id2.good()); | |
| 2421 ASSERT_TRUE(id3.good()); | |
| 2422 ASSERT_TRUE(id4.good()); | |
| 2423 EXPECT_FALSE(id1.Put(NAME, PSTR("fred"))); | |
| 2424 EXPECT_TRUE(id1.Put(NAME, PSTR("temp"))); | |
| 2425 EXPECT_TRUE(id2.Put(NAME, PSTR("bob"))); | |
| 2426 EXPECT_TRUE(id1.Put(NAME, PSTR("fred"))); | |
| 2427 EXPECT_FALSE(id3.Put(NAME, PSTR("greg"))); | |
| 2428 EXPECT_TRUE(id3.Put(NAME, PSTR("temp"))); | |
| 2429 EXPECT_TRUE(id4.Put(NAME, PSTR("sue"))); | |
| 2430 EXPECT_TRUE(id3.Put(NAME, PSTR("greg"))); | |
| 2431 id1.Put(IS_UNSYNCED, true); | |
| 2432 id2.Put(IS_UNSYNCED, true); | |
| 2433 id3.Put(IS_UNSYNCED, true); | |
| 2434 id4.Put(IS_UNSYNCED, true); | |
| 2435 } | |
| 2436 mock_server_->set_conflict_all_commits(true); | |
| 2437 syncer_->SyncShare(); | |
| 2438 ASSERT_TRUE(4 == mock_server_->commit_messages().size()); | |
| 2439 { | |
| 2440 ReadTransaction trans(dir, __FILE__, __LINE__); | |
| 2441 Entry id1(&trans, GET_BY_ID, ids_.FromNumber(1)); | |
| 2442 ASSERT_TRUE(id1.good()); | |
| 2443 EXPECT_TRUE(PSTR("fred") == id1.Get(NAME)); | |
| 2444 EXPECT_TRUE(root_id_ == id1.Get(PARENT_ID)); | |
| 2445 EXPECT_FALSE(id1.Get(IS_UNSYNCED)); | |
| 2446 Entry id2(&trans, GET_BY_ID, ids_.FromNumber(2)); | |
| 2447 ASSERT_TRUE(id2.good()); | |
| 2448 EXPECT_TRUE(PSTR("bob") == id2.Get(NAME)); | |
| 2449 EXPECT_TRUE(root_id_ == id2.Get(PARENT_ID)); | |
| 2450 EXPECT_FALSE(id2.Get(IS_UNSYNCED)); | |
| 2451 Entry id3(&trans, GET_BY_ID, ids_.FromNumber(3)); | |
| 2452 ASSERT_TRUE(id3.good()); | |
| 2453 EXPECT_TRUE(PSTR("greg") == id3.Get(NAME)); | |
| 2454 EXPECT_TRUE(root_id_ == id3.Get(PARENT_ID)); | |
| 2455 EXPECT_FALSE(id3.Get(IS_UNSYNCED)); | |
| 2456 Entry id4(&trans, GET_BY_ID, ids_.FromNumber(4)); | |
| 2457 ASSERT_TRUE(id4.good()); | |
| 2458 EXPECT_TRUE(PSTR("sue") == id4.Get(NAME)); | |
| 2459 EXPECT_TRUE(root_id_ == id4.Get(PARENT_ID)); | |
| 2460 EXPECT_FALSE(id4.Get(IS_UNSYNCED)); | |
| 2461 } | |
| 2462 syncer_events_.clear(); | |
| 2463 } | |
| 2464 | |
| 2465 // TODO(chron): New set of folder swap commit tests that don't rely on | |
| 2466 // transactional commits. | |
| 2467 TEST_F(SyncerTest, DISABLED_TripleFolderRotateCommit) { | |
| 2468 ScopedDirLookup dir(syncdb_.manager(), syncdb_.name()); | |
| 2469 CHECK(dir.good()); | |
| 2470 mock_server_->AddUpdateDirectory(1, 0, "bob", 1, 10); | |
| 2471 mock_server_->AddUpdateDirectory(2, 0, "fred", 1, 10); | |
| 2472 mock_server_->AddUpdateDirectory(3, 0, "sue", 1, 10); | |
| 2473 syncer_->SyncShare(); | |
| 2474 { | |
| 2475 WriteTransaction trans(dir, UNITTEST, __FILE__, __LINE__); | |
| 2476 MutableEntry id1(&trans, GET_BY_ID, ids_.FromNumber(1)); | |
| 2477 MutableEntry id2(&trans, GET_BY_ID, ids_.FromNumber(2)); | |
| 2478 MutableEntry id3(&trans, GET_BY_ID, ids_.FromNumber(3)); | |
| 2479 ASSERT_TRUE(id1.good()); | |
| 2480 ASSERT_TRUE(id2.good()); | |
| 2481 ASSERT_TRUE(id3.good()); | |
| 2482 EXPECT_FALSE(id1.Put(NAME, PSTR("sue"))); | |
| 2483 EXPECT_TRUE(id1.Put(NAME, PSTR("temp"))); | |
| 2484 EXPECT_TRUE(id2.Put(NAME, PSTR("bob"))); | |
| 2485 EXPECT_TRUE(id3.Put(NAME, PSTR("fred"))); | |
| 2486 EXPECT_TRUE(id1.Put(NAME, PSTR("sue"))); | |
| 2487 id1.Put(IS_UNSYNCED, true); | |
| 2488 id2.Put(IS_UNSYNCED, true); | |
| 2489 id3.Put(IS_UNSYNCED, true); | |
| 2490 } | |
| 2491 mock_server_->set_conflict_all_commits(true); | |
| 2492 syncer_->SyncShare(); | |
| 2493 ASSERT_TRUE(2 == mock_server_->commit_messages().size()); | |
| 2494 { | |
| 2495 ReadTransaction trans(dir, __FILE__, __LINE__); | |
| 2496 Entry id1(&trans, GET_BY_ID, ids_.FromNumber(1)); | |
| 2497 ASSERT_TRUE(id1.good()); | |
| 2498 EXPECT_TRUE(PSTR("sue") == id1.Get(NAME)); | |
| 2499 EXPECT_TRUE(root_id_ == id1.Get(PARENT_ID)); | |
| 2500 EXPECT_FALSE(id1.Get(IS_UNSYNCED)); | |
| 2501 Entry id2(&trans, GET_BY_ID, ids_.FromNumber(2)); | |
| 2502 ASSERT_TRUE(id2.good()); | |
| 2503 EXPECT_TRUE(PSTR("bob") == id2.Get(NAME)); | |
| 2504 EXPECT_TRUE(root_id_ == id2.Get(PARENT_ID)); | |
| 2505 EXPECT_FALSE(id2.Get(IS_UNSYNCED)); | |
| 2506 Entry id3(&trans, GET_BY_ID, ids_.FromNumber(3)); | |
| 2507 ASSERT_TRUE(id3.good()); | |
| 2508 EXPECT_TRUE(PSTR("fred") == id3.Get(NAME)); | |
| 2509 EXPECT_TRUE(root_id_ == id3.Get(PARENT_ID)); | |
| 2510 EXPECT_FALSE(id3.Get(IS_UNSYNCED)); | |
| 2511 } | |
| 2512 syncer_events_.clear(); | |
| 2513 } | |
| 2514 | |
| 2515 // TODO(chron): New set of folder swap commit tests that don't rely on | |
| 2516 // transactional commits. | |
| 2517 TEST_F(SyncerTest, DISABLED_ServerAndClientSwap) { | |
| 2518 ScopedDirLookup dir(syncdb_.manager(), syncdb_.name()); | |
| 2519 CHECK(dir.good()); | |
| 2520 mock_server_->AddUpdateDirectory(1, 0, "bob", 1, 10); | |
| 2521 mock_server_->AddUpdateDirectory(2, 0, "fred", 1, 10); | |
| 2522 mock_server_->AddUpdateDirectory(3, 0, "sue", 1, 10); | |
| 2523 mock_server_->AddUpdateDirectory(4, 0, "greg", 1, 10); | |
| 2524 syncer_->SyncShare(); | |
| 2525 { | |
| 2526 WriteTransaction trans(dir, UNITTEST, __FILE__, __LINE__); | |
| 2527 MutableEntry id1(&trans, GET_BY_ID, ids_.FromNumber(1)); | |
| 2528 MutableEntry id2(&trans, GET_BY_ID, ids_.FromNumber(2)); | |
| 2529 ASSERT_TRUE(id1.good()); | |
| 2530 ASSERT_TRUE(id2.good()); | |
| 2531 EXPECT_FALSE(id1.Put(NAME, PSTR("fred"))); | |
| 2532 EXPECT_TRUE(id1.Put(NAME, PSTR("temp"))); | |
| 2533 EXPECT_TRUE(id2.Put(NAME, PSTR("bob"))); | |
| 2534 EXPECT_TRUE(id1.Put(NAME, PSTR("fred"))); | |
| 2535 id1.Put(IS_UNSYNCED, true); | |
| 2536 id2.Put(IS_UNSYNCED, true); | |
| 2537 } | |
| 2538 mock_server_->set_conflict_all_commits(true); | |
| 2539 mock_server_->AddUpdateDirectory(3, 0, "greg", 2, 20); | |
| 2540 mock_server_->AddUpdateDirectory(4, 0, "sue", 2, 20); | |
| 2541 syncer_->SyncShare(); | |
| 2542 ASSERT_TRUE(2 == mock_server_->commit_messages().size()); | |
| 2543 { | |
| 2544 ReadTransaction trans(dir, __FILE__, __LINE__); | |
| 2545 Entry id1(&trans, GET_BY_ID, ids_.FromNumber(1)); | |
| 2546 ASSERT_TRUE(id1.good()); | |
| 2547 EXPECT_TRUE(PSTR("fred") == id1.Get(NAME)); | |
| 2548 EXPECT_TRUE(root_id_ == id1.Get(PARENT_ID)); | |
| 2549 EXPECT_FALSE(id1.Get(IS_UNSYNCED)); | |
| 2550 Entry id2(&trans, GET_BY_ID, ids_.FromNumber(2)); | |
| 2551 ASSERT_TRUE(id2.good()); | |
| 2552 EXPECT_TRUE(PSTR("bob") == id2.Get(NAME)); | |
| 2553 EXPECT_TRUE(root_id_ == id2.Get(PARENT_ID)); | |
| 2554 EXPECT_FALSE(id2.Get(IS_UNSYNCED)); | |
| 2555 Entry id3(&trans, GET_BY_ID, ids_.FromNumber(3)); | |
| 2556 ASSERT_TRUE(id3.good()); | |
| 2557 EXPECT_TRUE(PSTR("greg") == id3.Get(NAME)); | |
| 2558 EXPECT_TRUE(root_id_ == id3.Get(PARENT_ID)); | |
| 2559 EXPECT_FALSE(id3.Get(IS_UNSYNCED)); | |
| 2560 Entry id4(&trans, GET_BY_ID, ids_.FromNumber(4)); | |
| 2561 ASSERT_TRUE(id4.good()); | |
| 2562 EXPECT_TRUE(PSTR("sue") == id4.Get(NAME)); | |
| 2563 EXPECT_TRUE(root_id_ == id4.Get(PARENT_ID)); | |
| 2564 EXPECT_FALSE(id4.Get(IS_UNSYNCED)); | |
| 2565 } | |
| 2566 syncer_events_.clear(); | |
| 2567 } | |
| 2568 | |
| 2569 TEST_F(SyncerTest, CommitManyItemsInOneGo) { | 1993 TEST_F(SyncerTest, CommitManyItemsInOneGo) { |
| 2570 ScopedDirLookup dir(syncdb_.manager(), syncdb_.name()); | 1994 ScopedDirLookup dir(syncdb_.manager(), syncdb_.name()); |
| 2571 uint32 max_batches = 3; | 1995 uint32 max_batches = 3; |
| 2572 uint32 items_to_commit = kDefaultMaxCommitBatchSize * max_batches; | 1996 uint32 items_to_commit = kDefaultMaxCommitBatchSize * max_batches; |
| 2573 CHECK(dir.good()); | 1997 CHECK(dir.good()); |
| 2574 { | 1998 { |
| 2575 WriteTransaction trans(dir, UNITTEST, __FILE__, __LINE__); | 1999 WriteTransaction trans(dir, UNITTEST, __FILE__, __LINE__); |
| 2576 for (uint32 i = 0; i < items_to_commit; i++) { | 2000 for (uint32 i = 0; i < items_to_commit; i++) { |
| 2577 string nameutf8 = StringPrintf("%d", i); | 2001 string nameutf8 = StringPrintf("%d", i); |
| 2578 PathString name(nameutf8.begin(), nameutf8.end()); | 2002 PathString name(nameutf8.begin(), nameutf8.end()); |
| 2579 MutableEntry e(&trans, CREATE, trans.root_id(), name); | 2003 MutableEntry e(&trans, CREATE, trans.root_id(), name); |
| 2580 e.Put(IS_UNSYNCED, true); | 2004 e.Put(IS_UNSYNCED, true); |
| 2581 e.Put(IS_DIR, true); | 2005 e.Put(IS_DIR, true); |
| 2582 } | 2006 } |
| 2583 } | 2007 } |
| 2584 uint32 num_loops = 0; | 2008 uint32 num_loops = 0; |
| 2585 while (syncer_->SyncShare()) { | 2009 while (syncer_->SyncShare()) { |
| 2586 num_loops++; | 2010 num_loops++; |
| 2587 ASSERT_LT(num_loops, max_batches * 2); | 2011 ASSERT_LT(num_loops, max_batches * 2); |
| 2588 } | 2012 } |
| 2589 EXPECT_GE(mock_server_->commit_messages().size(), max_batches); | 2013 EXPECT_GE(mock_server_->commit_messages().size(), max_batches); |
| 2590 } | 2014 } |
| 2591 | 2015 |
| 2592 TEST_F(SyncerTest, HugeConflict) { | 2016 TEST_F(SyncerTest, HugeConflict) { |
| 2593 ScopedDirLookup dir(syncdb_.manager(), syncdb_.name()); | 2017 ScopedDirLookup dir(syncdb_.manager(), syncdb_.name()); |
| 2594 PathString name = PSTR("f"); | 2018 int item_count = 300; // We should be able to do 300 or 3000 w/o issue. |
| 2595 int item_count = 30; // We should be able to do 300 or 3000 w/o issue. | |
| 2596 CHECK(dir.good()); | 2019 CHECK(dir.good()); |
| 2020 |
| 2021 syncable::Id parent_id = ids_.NewServerId(); |
| 2022 syncable::Id last_id = parent_id; |
| 2023 vector<syncable::Id> tree_ids; |
| 2024 |
| 2025 // Create a lot of updates for which the parent does not exist yet. |
| 2026 // Generate a huge deep tree which should all fail to apply at first. |
| 2597 { | 2027 { |
| 2598 WriteTransaction trans(dir, UNITTEST, __FILE__, __LINE__); | 2028 WriteTransaction trans(dir, UNITTEST, __FILE__, __LINE__); |
| 2599 syncable::Id last_id = trans.root_id(); | 2029 for (int i = 0; i < item_count; i++) { |
| 2600 for (int i = 0; i < item_count ; i++) { | 2030 syncable::Id next_id = ids_.NewServerId(); |
| 2601 MutableEntry e(&trans, CREATE, last_id, name); | 2031 tree_ids.push_back(next_id); |
| 2602 e.Put(IS_UNSYNCED, true); | 2032 mock_server_->AddUpdateDirectory(next_id, last_id, "BOB", 2, 20); |
| 2603 e.Put(IS_DIR, true); | 2033 last_id = next_id; |
| 2604 last_id = e.Get(ID); | |
| 2605 } | 2034 } |
| 2606 } | 2035 } |
| 2036 |
| 2607 syncer_->SyncShare(); | 2037 syncer_->SyncShare(); |
| 2608 CHECK(dir.good()); | 2038 |
| 2039 // Check they're in the expected conflict state. |
| 2609 { | 2040 { |
| 2610 WriteTransaction trans(dir, UNITTEST, __FILE__, __LINE__); | 2041 ReadTransaction trans(dir, __FILE__, __LINE__); |
| 2611 MutableEntry e(&trans, GET_BY_PARENTID_AND_NAME, root_id_, name); | 2042 for (int i = 0; i < item_count; i++) { |
| 2612 syncable::Id in_root = e.Get(ID); | 2043 Entry e(&trans, GET_BY_ID, tree_ids[i]); |
| 2613 syncable::Id last_id = e.Get(ID); | 2044 // They should all exist but none should be applied. |
| 2614 for (int i = 0; i < item_count - 1 ; i++) { | |
| 2615 MutableEntry e(&trans, GET_BY_PARENTID_AND_NAME, last_id, name); | |
| 2616 ASSERT_TRUE(e.good()); | 2045 ASSERT_TRUE(e.good()); |
| 2617 mock_server_->AddUpdateDirectory(in_root, root_id_, "BOB", 2, 20); | 2046 EXPECT_TRUE(e.Get(IS_DEL)); |
| 2618 mock_server_->SetLastUpdateDeleted(); | 2047 EXPECT_TRUE(e.Get(IS_UNAPPLIED_UPDATE)); |
| 2619 if (0 == i) | |
| 2620 e.Put(IS_UNSYNCED, true); | |
| 2621 last_id = e.Get(ID); | |
| 2622 } | 2048 } |
| 2623 } | 2049 } |
| 2624 mock_server_->set_conflict_all_commits(true); | 2050 |
| 2051 // Add the missing parent directory. |
| 2052 mock_server_->AddUpdateDirectory(parent_id, TestIdFactory::root(), |
| 2053 "BOB", 2, 20); |
| 2625 syncer_->SyncShare(); | 2054 syncer_->SyncShare(); |
| 2626 syncer_->SyncShare(); | 2055 |
| 2627 syncer_->SyncShare(); | 2056 // Now they should all be OK. |
| 2628 CHECK(dir.good()); | 2057 { |
| 2058 ReadTransaction trans(dir, __FILE__, __LINE__); |
| 2059 for (int i = 0; i < item_count; i++) { |
| 2060 Entry e(&trans, GET_BY_ID, tree_ids[i]); |
| 2061 ASSERT_TRUE(e.good()); |
| 2062 EXPECT_FALSE(e.Get(IS_DEL)); |
| 2063 EXPECT_FALSE(e.Get(IS_UNAPPLIED_UPDATE)); |
| 2064 } |
| 2065 } |
| 2629 } | 2066 } |
| 2630 | 2067 |
| 2631 TEST_F(SyncerTest, CaseChangeNameClashConflict) { | 2068 TEST_F(SyncerTest, DontCrashOnCaseChange) { |
| 2632 ScopedDirLookup dir(syncdb_.manager(), syncdb_.name()); | 2069 ScopedDirLookup dir(syncdb_.manager(), syncdb_.name()); |
| 2633 CHECK(dir.good()); | 2070 CHECK(dir.good()); |
| 2634 mock_server_->AddUpdateDirectory(1, 0, "bob", 1, 10); | 2071 mock_server_->AddUpdateDirectory(1, 0, "bob", 1, 10); |
| 2635 syncer_->SyncShare(); | 2072 syncer_->SyncShare(); |
| 2636 { | 2073 { |
| 2637 WriteTransaction trans(dir, UNITTEST, __FILE__, __LINE__); | 2074 WriteTransaction trans(dir, UNITTEST, __FILE__, __LINE__); |
| 2638 MutableEntry e(&trans, GET_BY_ID, ids_.FromNumber(1)); | 2075 MutableEntry e(&trans, GET_BY_ID, ids_.FromNumber(1)); |
| 2639 ASSERT_TRUE(e.good()); | 2076 ASSERT_TRUE(e.good()); |
| 2640 e.Put(IS_UNSYNCED, true); | 2077 e.Put(IS_UNSYNCED, true); |
| 2641 } | 2078 } |
| 2642 mock_server_->set_conflict_all_commits(true); | 2079 mock_server_->set_conflict_all_commits(true); |
| 2643 mock_server_->AddUpdateDirectory(1, 0, "BOB", 2, 20); | 2080 mock_server_->AddUpdateDirectory(1, 0, "BOB", 2, 20); |
| 2644 syncer_->SyncShare(); // USED TO CAUSE AN ASSERT | 2081 syncer_->SyncShare(); // USED TO CAUSE AN ASSERT |
| 2645 syncer_events_.clear(); | 2082 syncer_events_.clear(); |
| 2646 } | 2083 } |
| 2647 | 2084 |
| 2648 TEST_F(SyncerTest, UnsyncedItemAndUpdate) { | 2085 TEST_F(SyncerTest, UnsyncedItemAndUpdate) { |
| 2649 ScopedDirLookup dir(syncdb_.manager(), syncdb_.name()); | 2086 ScopedDirLookup dir(syncdb_.manager(), syncdb_.name()); |
| 2650 CHECK(dir.good()); | 2087 CHECK(dir.good()); |
| 2651 mock_server_->AddUpdateDirectory(1, 0, "bob", 1, 10); | 2088 mock_server_->AddUpdateDirectory(1, 0, "bob", 1, 10); |
| 2652 syncer_->SyncShare(); | 2089 syncer_->SyncShare(); |
| 2653 mock_server_->set_conflict_all_commits(true); | 2090 mock_server_->set_conflict_all_commits(true); |
| 2654 mock_server_->AddUpdateDirectory(2, 0, "bob", 2, 20); | 2091 mock_server_->AddUpdateDirectory(2, 0, "bob", 2, 20); |
| 2655 syncer_->SyncShare(); // USED TO CAUSE AN ASSERT | 2092 syncer_->SyncShare(); // USED TO CAUSE AN ASSERT |
| 2656 syncer_events_.clear(); | 2093 syncer_events_.clear(); |
| 2657 } | 2094 } |
| 2658 | 2095 |
| 2659 TEST_F(SyncerTest, FolderMergeWithChildNameClash) { | |
| 2660 ScopedDirLookup dir(syncdb_.manager(), syncdb_.name()); | |
| 2661 CHECK(dir.good()); | |
| 2662 syncable::Id local_folder_id, root_id; | |
| 2663 mock_server_->AddUpdateDirectory(parent_id_, root_id_, "Folder2", 10, 10); | |
| 2664 mock_server_->AddUpdateBookmark(child_id_, parent_id_, "Bookmark", 10, 10); | |
| 2665 syncer_->SyncShare(); | |
| 2666 int64 local_folder_handle; | |
| 2667 { | |
| 2668 WriteTransaction wtrans(dir, UNITTEST, __FILE__, __LINE__); | |
| 2669 MutableEntry parent(&wtrans, CREATE, root_id_, PSTR("Folder")); | |
| 2670 ASSERT_TRUE(parent.good()); | |
| 2671 local_folder_id = parent.Get(ID); | |
| 2672 local_folder_handle = parent.Get(META_HANDLE); | |
| 2673 parent.Put(IS_DIR, true); | |
| 2674 parent.Put(IS_UNSYNCED, true); | |
| 2675 MutableEntry child(&wtrans, CREATE, parent.Get(ID), PSTR("Bookmark")); | |
| 2676 ASSERT_TRUE(child.good()); | |
| 2677 WriteTestDataToEntry(&wtrans, &child); | |
| 2678 } | |
| 2679 mock_server_->AddUpdateDirectory(parent_id_, root_id_, "Folder", 20, 20); | |
| 2680 mock_server_->set_conflict_all_commits(true); | |
| 2681 LoopSyncShare(syncer_); | |
| 2682 LoopSyncShare(syncer_); | |
| 2683 { | |
| 2684 ReadTransaction trans(dir, __FILE__, __LINE__); | |
| 2685 Directory::ChildHandles children; | |
| 2686 dir->GetChildHandles(&trans, root_id_, &children); | |
| 2687 ASSERT_TRUE(2 == children.size()); | |
| 2688 Entry parent(&trans, GET_BY_ID, parent_id_); | |
| 2689 ASSERT_TRUE(parent.good()); | |
| 2690 EXPECT_TRUE(parent.Get(NAME) == PSTR("Folder")); | |
| 2691 if (local_folder_handle == children[0]) { | |
| 2692 EXPECT_TRUE(children[1] == parent.Get(META_HANDLE)); | |
| 2693 } else { | |
| 2694 EXPECT_TRUE(children[0] == parent.Get(META_HANDLE)); | |
| 2695 EXPECT_TRUE(children[1] == local_folder_handle); | |
| 2696 } | |
| 2697 dir->GetChildHandles(&trans, local_folder_id, &children); | |
| 2698 EXPECT_TRUE(1 == children.size()); | |
| 2699 dir->GetChildHandles(&trans, parent_id_, &children); | |
| 2700 EXPECT_TRUE(1 == children.size()); | |
| 2701 Directory::UnappliedUpdateMetaHandles unapplied; | |
| 2702 dir->GetUnappliedUpdateMetaHandles(&trans, &unapplied); | |
| 2703 EXPECT_TRUE(0 == unapplied.size()); | |
| 2704 syncable::Directory::UnsyncedMetaHandles unsynced; | |
| 2705 dir->GetUnsyncedMetaHandles(&trans, &unsynced); | |
| 2706 EXPECT_TRUE(2 == unsynced.size()); | |
| 2707 } | |
| 2708 mock_server_->set_conflict_all_commits(false); | |
| 2709 syncer_->SyncShare(); | |
| 2710 { | |
| 2711 ReadTransaction trans(dir, __FILE__, __LINE__); | |
| 2712 syncable::Directory::UnsyncedMetaHandles unsynced; | |
| 2713 dir->GetUnsyncedMetaHandles(&trans, &unsynced); | |
| 2714 EXPECT_TRUE(0 == unsynced.size()); | |
| 2715 } | |
| 2716 syncer_events_.clear(); | |
| 2717 } | |
| 2718 | |
| 2719 TEST_F(SyncerTest, NewEntryAndAlteredServerEntrySharePath) { | 2096 TEST_F(SyncerTest, NewEntryAndAlteredServerEntrySharePath) { |
| 2720 ScopedDirLookup dir(syncdb_.manager(), syncdb_.name()); | 2097 ScopedDirLookup dir(syncdb_.manager(), syncdb_.name()); |
| 2721 CHECK(dir.good()); | 2098 CHECK(dir.good()); |
| 2722 mock_server_->AddUpdateBookmark(1, 0, "Foo.htm", 10, 10); | 2099 mock_server_->AddUpdateBookmark(1, 0, "Foo.htm", 10, 10); |
| 2723 syncer_->SyncShare(); | 2100 syncer_->SyncShare(); |
| 2724 int64 local_folder_handle; | 2101 int64 local_folder_handle; |
| 2725 syncable::Id local_folder_id; | 2102 syncable::Id local_folder_id; |
| 2726 { | 2103 { |
| 2727 WriteTransaction wtrans(dir, UNITTEST, __FILE__, __LINE__); | 2104 WriteTransaction wtrans(dir, UNITTEST, __FILE__, __LINE__); |
| 2728 MutableEntry new_entry(&wtrans, CREATE, wtrans.root_id(), PSTR("Bar.htm")); | 2105 MutableEntry new_entry(&wtrans, CREATE, wtrans.root_id(), PSTR("Bar.htm")); |
| (...skipping 18 matching lines...) Expand all Loading... |
| 2747 CHECK(dir.good()); | 2124 CHECK(dir.good()); |
| 2748 mock_server_->AddUpdateDirectory(1, 0, "A", 10, 10); | 2125 mock_server_->AddUpdateDirectory(1, 0, "A", 10, 10); |
| 2749 mock_server_->AddUpdateDirectory(2, 0, "B", 10, 10); | 2126 mock_server_->AddUpdateDirectory(2, 0, "B", 10, 10); |
| 2750 syncer_->SyncShare(); | 2127 syncer_->SyncShare(); |
| 2751 { | 2128 { |
| 2752 WriteTransaction wtrans(dir, UNITTEST, __FILE__, __LINE__); | 2129 WriteTransaction wtrans(dir, UNITTEST, __FILE__, __LINE__); |
| 2753 MutableEntry A(&wtrans, GET_BY_ID, ids_.FromNumber(1)); | 2130 MutableEntry A(&wtrans, GET_BY_ID, ids_.FromNumber(1)); |
| 2754 ASSERT_TRUE(A.good()); | 2131 ASSERT_TRUE(A.good()); |
| 2755 A.Put(IS_UNSYNCED, true); | 2132 A.Put(IS_UNSYNCED, true); |
| 2756 ASSERT_TRUE(A.Put(PARENT_ID, ids_.FromNumber(2))); | 2133 ASSERT_TRUE(A.Put(PARENT_ID, ids_.FromNumber(2))); |
| 2757 ASSERT_TRUE(A.Put(NAME, PSTR("B"))); | 2134 ASSERT_TRUE(A.Put(NON_UNIQUE_NAME, PSTR("B"))); |
| 2758 } | 2135 } |
| 2759 mock_server_->AddUpdateDirectory(2, 1, "A", 20, 20); | 2136 mock_server_->AddUpdateDirectory(2, 1, "A", 20, 20); |
| 2760 mock_server_->set_conflict_all_commits(true); | 2137 mock_server_->set_conflict_all_commits(true); |
| 2761 syncer_->SyncShare(); | 2138 syncer_->SyncShare(); |
| 2762 syncer_events_.clear(); | 2139 syncer_events_.clear(); |
| 2763 { | 2140 { |
| 2764 WriteTransaction wtrans(dir, UNITTEST, __FILE__, __LINE__); | 2141 WriteTransaction wtrans(dir, UNITTEST, __FILE__, __LINE__); |
| 2765 MutableEntry A(&wtrans, GET_BY_ID, ids_.FromNumber(1)); | 2142 MutableEntry A(&wtrans, GET_BY_ID, ids_.FromNumber(1)); |
| 2766 ASSERT_TRUE(A.good()); | 2143 ASSERT_TRUE(A.good()); |
| 2767 MutableEntry B(&wtrans, GET_BY_ID, ids_.FromNumber(2)); | 2144 MutableEntry B(&wtrans, GET_BY_ID, ids_.FromNumber(2)); |
| 2768 ASSERT_TRUE(B.good()); | 2145 ASSERT_TRUE(B.good()); |
| 2769 EXPECT_TRUE(A.Get(NAME) == PSTR("B")); | 2146 EXPECT_TRUE(A.Get(NON_UNIQUE_NAME) == PSTR("B")); |
| 2770 EXPECT_TRUE(B.Get(NAME) == PSTR("B")); | 2147 EXPECT_TRUE(B.Get(NON_UNIQUE_NAME) == PSTR("B")); |
| 2771 } | 2148 } |
| 2772 } | 2149 } |
| 2773 | 2150 |
| 2774 TEST_F(SyncerTest, ConflictSetClassificationError) { | 2151 TEST_F(SyncerTest, ConflictSetClassificationError) { |
| 2775 // This code used to cause a CHECK failure because we incorrectly thought | 2152 // This code used to cause a CHECK failure because we incorrectly thought |
| 2776 // a set was only unapplied updates. | 2153 // a set was only unapplied updates. |
| 2777 ScopedDirLookup dir(syncdb_.manager(), syncdb_.name()); | 2154 ScopedDirLookup dir(syncdb_.manager(), syncdb_.name()); |
| 2778 CHECK(dir.good()); | 2155 CHECK(dir.good()); |
| 2779 mock_server_->AddUpdateDirectory(1, 0, "A", 10, 10); | 2156 mock_server_->AddUpdateDirectory(1, 0, "A", 10, 10); |
| 2780 mock_server_->AddUpdateDirectory(2, 0, "B", 10, 10); | 2157 mock_server_->AddUpdateDirectory(2, 0, "B", 10, 10); |
| 2781 mock_server_->set_conflict_all_commits(true); | 2158 mock_server_->set_conflict_all_commits(true); |
| 2782 syncer_->SyncShare(); | 2159 syncer_->SyncShare(); |
| 2783 { | 2160 { |
| 2784 WriteTransaction wtrans(dir, UNITTEST, __FILE__, __LINE__); | 2161 WriteTransaction wtrans(dir, UNITTEST, __FILE__, __LINE__); |
| 2785 MutableEntry A(&wtrans, GET_BY_ID, ids_.FromNumber(1)); | 2162 MutableEntry A(&wtrans, GET_BY_ID, ids_.FromNumber(1)); |
| 2786 ASSERT_TRUE(A.good()); | 2163 ASSERT_TRUE(A.good()); |
| 2787 A.Put(IS_UNSYNCED, true); | 2164 A.Put(IS_UNSYNCED, true); |
| 2788 A.Put(IS_UNAPPLIED_UPDATE, true); | 2165 A.Put(IS_UNAPPLIED_UPDATE, true); |
| 2789 A.Put(SERVER_NAME, PSTR("B")); | 2166 A.Put(SERVER_NON_UNIQUE_NAME, PSTR("B")); |
| 2790 MutableEntry B(&wtrans, GET_BY_ID, ids_.FromNumber(2)); | 2167 MutableEntry B(&wtrans, GET_BY_ID, ids_.FromNumber(2)); |
| 2791 ASSERT_TRUE(B.good()); | 2168 ASSERT_TRUE(B.good()); |
| 2792 B.Put(IS_UNAPPLIED_UPDATE, true); | 2169 B.Put(IS_UNAPPLIED_UPDATE, true); |
| 2793 B.Put(SERVER_NAME, PSTR("A")); | 2170 B.Put(SERVER_NON_UNIQUE_NAME, PSTR("A")); |
| 2794 } | 2171 } |
| 2795 syncer_->SyncShare(); | 2172 syncer_->SyncShare(); |
| 2796 syncer_events_.clear(); | 2173 syncer_events_.clear(); |
| 2797 } | 2174 } |
| 2798 | 2175 |
| 2799 TEST_F(SyncerTest, SwapEntryNames) { | 2176 TEST_F(SyncerTest, SwapEntryNames) { |
| 2800 // Simple transaction test. | 2177 // Simple transaction test. |
| 2801 ScopedDirLookup dir(syncdb_.manager(), syncdb_.name()); | 2178 ScopedDirLookup dir(syncdb_.manager(), syncdb_.name()); |
| 2802 CHECK(dir.good()); | 2179 CHECK(dir.good()); |
| 2803 mock_server_->AddUpdateDirectory(1, 0, "A", 10, 10); | 2180 mock_server_->AddUpdateDirectory(1, 0, "A", 10, 10); |
| 2804 mock_server_->AddUpdateDirectory(2, 0, "B", 10, 10); | 2181 mock_server_->AddUpdateDirectory(2, 0, "B", 10, 10); |
| 2805 mock_server_->set_conflict_all_commits(true); | 2182 mock_server_->set_conflict_all_commits(true); |
| 2806 syncer_->SyncShare(); | 2183 syncer_->SyncShare(); |
| 2807 { | 2184 { |
| 2808 WriteTransaction wtrans(dir, UNITTEST, __FILE__, __LINE__); | 2185 WriteTransaction wtrans(dir, UNITTEST, __FILE__, __LINE__); |
| 2809 MutableEntry A(&wtrans, GET_BY_ID, ids_.FromNumber(1)); | 2186 MutableEntry A(&wtrans, GET_BY_ID, ids_.FromNumber(1)); |
| 2810 ASSERT_TRUE(A.good()); | 2187 ASSERT_TRUE(A.good()); |
| 2811 A.Put(IS_UNSYNCED, true); | 2188 A.Put(IS_UNSYNCED, true); |
| 2812 MutableEntry B(&wtrans, GET_BY_ID, ids_.FromNumber(2)); | 2189 MutableEntry B(&wtrans, GET_BY_ID, ids_.FromNumber(2)); |
| 2813 ASSERT_TRUE(B.good()); | 2190 ASSERT_TRUE(B.good()); |
| 2814 B.Put(IS_UNSYNCED, true); | 2191 B.Put(IS_UNSYNCED, true); |
| 2815 ASSERT_TRUE(A.Put(NAME, PSTR("C"))); | 2192 ASSERT_TRUE(A.Put(NON_UNIQUE_NAME, PSTR("C"))); |
| 2816 ASSERT_TRUE(B.Put(NAME, PSTR("A"))); | 2193 ASSERT_TRUE(B.Put(NON_UNIQUE_NAME, PSTR("A"))); |
| 2817 ASSERT_TRUE(A.Put(NAME, PSTR("B"))); | 2194 ASSERT_TRUE(A.Put(NON_UNIQUE_NAME, PSTR("B"))); |
| 2818 } | 2195 } |
| 2819 syncer_->SyncShare(); | 2196 syncer_->SyncShare(); |
| 2820 syncer_events_.clear(); | 2197 syncer_events_.clear(); |
| 2821 } | 2198 } |
| 2822 | 2199 |
| 2823 TEST_F(SyncerTest, DualDeletionWithNewItemNameClash) { | 2200 TEST_F(SyncerTest, DualDeletionWithNewItemNameClash) { |
| 2824 ScopedDirLookup dir(syncdb_.manager(), syncdb_.name()); | 2201 ScopedDirLookup dir(syncdb_.manager(), syncdb_.name()); |
| 2825 CHECK(dir.good()); | 2202 CHECK(dir.good()); |
| 2826 mock_server_->AddUpdateDirectory(1, 0, "A", 10, 10); | 2203 mock_server_->AddUpdateDirectory(1, 0, "A", 10, 10); |
| 2827 mock_server_->AddUpdateBookmark(2, 0, "B", 10, 10); | 2204 mock_server_->AddUpdateBookmark(2, 0, "B", 10, 10); |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2874 EXPECT_TRUE(bob.Get(IS_UNSYNCED)); | 2251 EXPECT_TRUE(bob.Get(IS_UNSYNCED)); |
| 2875 EXPECT_FALSE(fred.Get(IS_UNAPPLIED_UPDATE)); | 2252 EXPECT_FALSE(fred.Get(IS_UNAPPLIED_UPDATE)); |
| 2876 EXPECT_FALSE(bob.Get(IS_UNAPPLIED_UPDATE)); | 2253 EXPECT_FALSE(bob.Get(IS_UNAPPLIED_UPDATE)); |
| 2877 } | 2254 } |
| 2878 syncer_events_.clear(); | 2255 syncer_events_.clear(); |
| 2879 } | 2256 } |
| 2880 | 2257 |
| 2881 TEST_F(SyncerTest, ResolveWeWroteTheyDeleted) { | 2258 TEST_F(SyncerTest, ResolveWeWroteTheyDeleted) { |
| 2882 ScopedDirLookup dir(syncdb_.manager(), syncdb_.name()); | 2259 ScopedDirLookup dir(syncdb_.manager(), syncdb_.name()); |
| 2883 CHECK(dir.good()); | 2260 CHECK(dir.good()); |
| 2261 |
| 2262 int64 bob_metahandle; |
| 2263 |
| 2884 mock_server_->AddUpdateBookmark(1, 0, "bob", 1, 10); | 2264 mock_server_->AddUpdateBookmark(1, 0, "bob", 1, 10); |
| 2885 syncer_->SyncShare(); | 2265 syncer_->SyncShare(); |
| 2886 { | 2266 { |
| 2887 WriteTransaction trans(dir, UNITTEST, __FILE__, __LINE__); | 2267 WriteTransaction trans(dir, UNITTEST, __FILE__, __LINE__); |
| 2888 MutableEntry bob(&trans, GET_BY_ID, ids_.FromNumber(1)); | 2268 MutableEntry bob(&trans, GET_BY_ID, ids_.FromNumber(1)); |
| 2889 ASSERT_TRUE(bob.good()); | 2269 ASSERT_TRUE(bob.good()); |
| 2270 bob_metahandle = bob.Get(META_HANDLE); |
| 2890 WriteTestDataToEntry(&trans, &bob); | 2271 WriteTestDataToEntry(&trans, &bob); |
| 2891 } | 2272 } |
| 2892 mock_server_->AddUpdateBookmark(1, 0, "bob", 2, 10); | 2273 mock_server_->AddUpdateBookmark(1, 0, "bob", 2, 10); |
| 2893 mock_server_->SetLastUpdateDeleted(); | 2274 mock_server_->SetLastUpdateDeleted(); |
| 2894 mock_server_->set_conflict_all_commits(true); | 2275 mock_server_->set_conflict_all_commits(true); |
| 2895 syncer_->SyncShare(); | 2276 syncer_->SyncShare(); |
| 2896 syncer_->SyncShare(); | 2277 syncer_->SyncShare(); |
| 2897 { | 2278 { |
| 2898 ReadTransaction trans(dir, __FILE__, __LINE__); | 2279 ReadTransaction trans(dir, __FILE__, __LINE__); |
| 2899 Entry bob(&trans, GET_BY_PARENTID_AND_NAME, trans.root_id(), PSTR("bob")); | 2280 Entry bob(&trans, GET_BY_HANDLE, bob_metahandle); |
| 2900 ASSERT_TRUE(bob.good()); | 2281 ASSERT_TRUE(bob.good()); |
| 2901 EXPECT_TRUE(bob.Get(IS_UNSYNCED)); | 2282 EXPECT_TRUE(bob.Get(IS_UNSYNCED)); |
| 2902 EXPECT_FALSE(bob.Get(ID).ServerKnows()); | 2283 EXPECT_FALSE(bob.Get(ID).ServerKnows()); |
| 2903 EXPECT_FALSE(bob.Get(IS_UNAPPLIED_UPDATE)); | 2284 EXPECT_FALSE(bob.Get(IS_UNAPPLIED_UPDATE)); |
| 2904 EXPECT_FALSE(bob.Get(IS_DEL)); | 2285 EXPECT_FALSE(bob.Get(IS_DEL)); |
| 2905 } | 2286 } |
| 2906 syncer_events_.clear(); | 2287 syncer_events_.clear(); |
| 2907 } | 2288 } |
| 2908 | 2289 |
| 2909 // This test is disabled because we actually enforce the opposite behavior in: | |
| 2910 // ConflictResolverMergesLocalDeleteAndServerUpdate for bookmarks. | |
| 2911 TEST_F(SyncerTest, DISABLED_ResolveWeDeletedTheyWrote) { | |
| 2912 ScopedDirLookup dir(syncdb_.manager(), syncdb_.name()); | |
| 2913 CHECK(dir.good()); | |
| 2914 mock_server_->AddUpdateBookmark(1, 0, "bob", 1, 10); | |
| 2915 syncer_->SyncShare(); | |
| 2916 { | |
| 2917 WriteTransaction trans(dir, UNITTEST, __FILE__, __LINE__); | |
| 2918 MutableEntry bob(&trans, GET_BY_ID, ids_.FromNumber(1)); | |
| 2919 ASSERT_TRUE(bob.good()); | |
| 2920 bob.Put(IS_UNSYNCED, true); | |
| 2921 bob.Put(IS_DEL, true); | |
| 2922 } | |
| 2923 mock_server_->AddUpdateBookmark(1, 0, "bob", 2, 10); | |
| 2924 mock_server_->set_conflict_all_commits(true); | |
| 2925 syncer_->SyncShare(); | |
| 2926 syncer_->SyncShare(); | |
| 2927 { | |
| 2928 ReadTransaction trans(dir, __FILE__, __LINE__); | |
| 2929 Entry bob(&trans, GET_BY_PARENTID_AND_NAME, trans.root_id(), PSTR("bob")); | |
| 2930 ASSERT_TRUE(bob.good()); | |
| 2931 EXPECT_TRUE(bob.Get(ID) == ids_.FromNumber(1)); | |
| 2932 EXPECT_FALSE(bob.Get(IS_UNSYNCED)); | |
| 2933 EXPECT_FALSE(bob.Get(IS_UNAPPLIED_UPDATE)); | |
| 2934 EXPECT_FALSE(bob.Get(IS_DEL)); | |
| 2935 } | |
| 2936 syncer_events_.clear(); | |
| 2937 } | |
| 2938 | |
| 2939 TEST_F(SyncerTest, ServerDeletingFolderWeHaveMovedSomethingInto) { | 2290 TEST_F(SyncerTest, ServerDeletingFolderWeHaveMovedSomethingInto) { |
| 2940 ScopedDirLookup dir(syncdb_.manager(), syncdb_.name()); | 2291 ScopedDirLookup dir(syncdb_.manager(), syncdb_.name()); |
| 2941 CHECK(dir.good()); | 2292 CHECK(dir.good()); |
| 2942 mock_server_->AddUpdateDirectory(1, 0, "bob", 1, 10); | 2293 |
| 2943 mock_server_->AddUpdateDirectory(2, 0, "fred", 1, 10); | 2294 syncable::Id bob_id = ids_.NewServerId(); |
| 2295 syncable::Id fred_id = ids_.NewServerId(); |
| 2296 |
| 2297 mock_server_->AddUpdateDirectory(bob_id, TestIdFactory::root(), |
| 2298 "bob", 1, 10); |
| 2299 mock_server_->AddUpdateDirectory(fred_id, TestIdFactory::root(), |
| 2300 "fred", 1, 10); |
| 2944 syncer_->SyncShare(); | 2301 syncer_->SyncShare(); |
| 2945 { | 2302 { |
| 2946 WriteTransaction trans(dir, UNITTEST, __FILE__, __LINE__); | 2303 WriteTransaction trans(dir, UNITTEST, __FILE__, __LINE__); |
| 2947 MutableEntry bob(&trans, GET_BY_ID, ids_.FromNumber(1)); | 2304 MutableEntry bob(&trans, GET_BY_ID, bob_id); |
| 2948 ASSERT_TRUE(bob.good()); | 2305 ASSERT_TRUE(bob.good()); |
| 2949 bob.Put(IS_UNSYNCED, true); | 2306 bob.Put(IS_UNSYNCED, true); |
| 2950 bob.Put(PARENT_ID, ids_.FromNumber(2)); | 2307 bob.Put(PARENT_ID, fred_id); |
| 2951 } | 2308 } |
| 2952 mock_server_->AddUpdateDirectory(2, 0, "fred", 2, 20); | 2309 mock_server_->AddUpdateDirectory(fred_id, TestIdFactory::root(), |
| 2310 "fred", 2, 20); |
| 2953 mock_server_->SetLastUpdateDeleted(); | 2311 mock_server_->SetLastUpdateDeleted(); |
| 2954 mock_server_->set_conflict_all_commits(true); | 2312 mock_server_->set_conflict_all_commits(true); |
| 2955 syncer_->SyncShare(); | 2313 syncer_->SyncShare(); |
| 2956 syncer_->SyncShare(); | 2314 syncer_->SyncShare(); |
| 2957 { | 2315 { |
| 2958 ReadTransaction trans(dir, __FILE__, __LINE__); | 2316 ReadTransaction trans(dir, __FILE__, __LINE__); |
| 2959 Entry bob(&trans, GET_BY_ID, ids_.FromNumber(1)); | 2317 |
| 2318 Entry bob(&trans, GET_BY_ID, bob_id); |
| 2960 ASSERT_TRUE(bob.good()); | 2319 ASSERT_TRUE(bob.good()); |
| 2961 Entry fred(&trans, GET_BY_PARENTID_AND_NAME, trans.root_id(), PSTR("fred")); | 2320 EXPECT_TRUE(bob.Get(IS_UNSYNCED)); |
| 2321 EXPECT_FALSE(bob.Get(IS_UNAPPLIED_UPDATE)); |
| 2322 EXPECT_TRUE(bob.Get(NON_UNIQUE_NAME) == PSTR("bob")); |
| 2323 EXPECT_NE(bob.Get(PARENT_ID), fred_id); |
| 2324 |
| 2325 // Entry was deleted and reborn. |
| 2326 Entry dead_fred(&trans, GET_BY_ID, fred_id); |
| 2327 EXPECT_FALSE(dead_fred.good()); |
| 2328 |
| 2329 // Reborn fred |
| 2330 Entry fred(&trans, GET_BY_ID, bob.Get(PARENT_ID)); |
| 2962 ASSERT_TRUE(fred.good()); | 2331 ASSERT_TRUE(fred.good()); |
| 2332 EXPECT_TRUE(fred.Get(PARENT_ID) == trans.root_id()); |
| 2333 EXPECT_EQ(PSTR("fred"), fred.Get(NON_UNIQUE_NAME)); |
| 2963 EXPECT_TRUE(fred.Get(IS_UNSYNCED)); | 2334 EXPECT_TRUE(fred.Get(IS_UNSYNCED)); |
| 2964 EXPECT_TRUE(bob.Get(IS_UNSYNCED)); | |
| 2965 EXPECT_TRUE(bob.Get(PARENT_ID) == fred.Get(ID)); | |
| 2966 EXPECT_FALSE(fred.Get(IS_UNAPPLIED_UPDATE)); | 2335 EXPECT_FALSE(fred.Get(IS_UNAPPLIED_UPDATE)); |
| 2967 EXPECT_FALSE(bob.Get(IS_UNAPPLIED_UPDATE)); | |
| 2968 } | 2336 } |
| 2969 syncer_events_.clear(); | 2337 syncer_events_.clear(); |
| 2970 } | 2338 } |
| 2971 | 2339 |
| 2972 // TODO(ncarter): This test is bogus, but it actually seems to hit an | 2340 // TODO(ncarter): This test is bogus, but it actually seems to hit an |
| 2973 // interesting case the 4th time SyncShare is called. | 2341 // interesting case the 4th time SyncShare is called. |
| 2342 // TODO(chron): The fourth time that SyncShare is called it crashes. |
| 2343 // This seems to be due to a bug in the conflict set building logic. |
| 2974 TEST_F(SyncerTest, DISABLED_ServerDeletingFolderWeHaveAnOpenEntryIn) { | 2344 TEST_F(SyncerTest, DISABLED_ServerDeletingFolderWeHaveAnOpenEntryIn) { |
| 2975 ScopedDirLookup dir(syncdb_.manager(), syncdb_.name()); | 2345 ScopedDirLookup dir(syncdb_.manager(), syncdb_.name()); |
| 2976 CHECK(dir.good()); | 2346 CHECK(dir.good()); |
| 2977 mock_server_->AddUpdateBookmark(1, 0, "bob", 1, 10); | 2347 mock_server_->AddUpdateBookmark(1, 0, "bob", 1, 10); |
| 2978 mock_server_->AddUpdateDirectory(2, 0, "fred", 1, 10); | 2348 mock_server_->AddUpdateDirectory(2, 0, "fred", 1, 10); |
| 2979 syncer_->SyncShare(state_.get()); | 2349 syncer_->SyncShare(state_.get()); |
| 2980 { | 2350 { |
| 2981 WriteTransaction trans(dir, UNITTEST, __FILE__, __LINE__); | 2351 WriteTransaction trans(dir, UNITTEST, __FILE__, __LINE__); |
| 2982 MutableEntry bob(&trans, GET_BY_ID, ids_.FromNumber(1)); | 2352 MutableEntry bob(&trans, GET_BY_ID, ids_.FromNumber(1)); |
| 2983 ASSERT_TRUE(bob.good()); | 2353 ASSERT_TRUE(bob.good()); |
| (...skipping 20 matching lines...) Expand all Loading... |
| 3004 syncer_->SyncShare(state_.get()); | 2374 syncer_->SyncShare(state_.get()); |
| 3005 syncer_->SyncShare(state_.get()); | 2375 syncer_->SyncShare(state_.get()); |
| 3006 syncer_->SyncShare(state_.get()); | 2376 syncer_->SyncShare(state_.get()); |
| 3007 syncer_->SyncShare(state_.get()); | 2377 syncer_->SyncShare(state_.get()); |
| 3008 syncer_->SyncShare(state_.get()); | 2378 syncer_->SyncShare(state_.get()); |
| 3009 EXPECT_TRUE(0 == syncer_events_.size()); | 2379 EXPECT_TRUE(0 == syncer_events_.size()); |
| 3010 { | 2380 { |
| 3011 ReadTransaction trans(dir, __FILE__, __LINE__); | 2381 ReadTransaction trans(dir, __FILE__, __LINE__); |
| 3012 Entry bob(&trans, GET_BY_ID, ids_.FromNumber(1)); | 2382 Entry bob(&trans, GET_BY_ID, ids_.FromNumber(1)); |
| 3013 ASSERT_TRUE(bob.good()); | 2383 ASSERT_TRUE(bob.good()); |
| 3014 Entry fred(&trans, GET_BY_PARENTID_AND_NAME, trans.root_id(), PSTR("fred")); | 2384 Id fred_id = |
| 2385 GetOnlyEntryWithName(&trans, TestIdFactory::root(), PSTR("fred")); |
| 2386 Entry fred(&trans, GET_BY_ID, fred_id); |
| 3015 ASSERT_TRUE(fred.good()); | 2387 ASSERT_TRUE(fred.good()); |
| 3016 EXPECT_FALSE(fred.Get(IS_UNSYNCED)); | 2388 EXPECT_FALSE(fred.Get(IS_UNSYNCED)); |
| 3017 EXPECT_TRUE(fred.Get(IS_UNAPPLIED_UPDATE)); | 2389 EXPECT_TRUE(fred.Get(IS_UNAPPLIED_UPDATE)); |
| 3018 EXPECT_TRUE(bob.Get(PARENT_ID) == fred.Get(ID)); | 2390 EXPECT_TRUE(bob.Get(PARENT_ID) == fred.Get(ID)); |
| 3019 EXPECT_FALSE(bob.Get(IS_UNAPPLIED_UPDATE)); | 2391 EXPECT_FALSE(bob.Get(IS_UNAPPLIED_UPDATE)); |
| 3020 } | 2392 } |
| 3021 syncer_events_.clear(); | 2393 syncer_events_.clear(); |
| 3022 } | 2394 } |
| 3023 | 2395 |
| 2396 |
| 3024 TEST_F(SyncerTest, WeMovedSomethingIntoAFolderServerHasDeleted) { | 2397 TEST_F(SyncerTest, WeMovedSomethingIntoAFolderServerHasDeleted) { |
| 3025 ScopedDirLookup dir(syncdb_.manager(), syncdb_.name()); | 2398 ScopedDirLookup dir(syncdb_.manager(), syncdb_.name()); |
| 3026 CHECK(dir.good()); | 2399 CHECK(dir.good()); |
| 3027 mock_server_->AddUpdateDirectory(1, 0, "bob", 1, 10); | 2400 |
| 3028 mock_server_->AddUpdateDirectory(2, 0, "fred", 1, 10); | 2401 syncable::Id bob_id = ids_.NewServerId(); |
| 2402 syncable::Id fred_id = ids_.NewServerId(); |
| 2403 |
| 2404 mock_server_->AddUpdateDirectory(bob_id, TestIdFactory::root(), |
| 2405 "bob", 1, 10); |
| 2406 mock_server_->AddUpdateDirectory(fred_id, TestIdFactory::root(), |
| 2407 "fred", 1, 10); |
| 3029 syncer_->SyncShare(); | 2408 syncer_->SyncShare(); |
| 3030 { | 2409 { |
| 3031 WriteTransaction trans(dir, UNITTEST, __FILE__, __LINE__); | 2410 WriteTransaction trans(dir, UNITTEST, __FILE__, __LINE__); |
| 3032 MutableEntry bob(&trans, GET_BY_ID, ids_.FromNumber(1)); | 2411 Entry fred(&trans, GET_BY_ID, fred_id); |
| 2412 ASSERT_TRUE(fred.good()); |
| 2413 |
| 2414 MutableEntry bob(&trans, GET_BY_ID, bob_id); |
| 3033 ASSERT_TRUE(bob.good()); | 2415 ASSERT_TRUE(bob.good()); |
| 3034 bob.Put(IS_UNSYNCED, true); | 2416 bob.Put(IS_UNSYNCED, true); |
| 3035 bob.Put(PARENT_ID, ids_.FromNumber(2)); | 2417 bob.Put(PARENT_ID, fred_id); |
| 3036 } | 2418 } |
| 3037 mock_server_->AddUpdateDirectory(2, 0, "fred", 2, 20); | 2419 mock_server_->AddUpdateDirectory(fred_id, TestIdFactory::root(), |
| 2420 "fred", 2, 20); |
| 3038 mock_server_->SetLastUpdateDeleted(); | 2421 mock_server_->SetLastUpdateDeleted(); |
| 3039 mock_server_->set_conflict_all_commits(true); | 2422 mock_server_->set_conflict_all_commits(true); |
| 3040 syncer_->SyncShare(); | 2423 syncer_->SyncShare(); |
| 3041 syncer_->SyncShare(); | 2424 syncer_->SyncShare(); |
| 3042 { | 2425 { |
| 3043 ReadTransaction trans(dir, __FILE__, __LINE__); | 2426 ReadTransaction trans(dir, __FILE__, __LINE__); |
| 3044 Entry bob(&trans, GET_BY_ID, ids_.FromNumber(1)); | 2427 Entry bob(&trans, GET_BY_ID, bob_id); |
| 3045 ASSERT_TRUE(bob.good()); | 2428 ASSERT_TRUE(bob.good()); |
| 3046 Entry fred(&trans, GET_BY_PATH, PSTR("fred")); | 2429 |
| 3047 ASSERT_TRUE(fred.good()); | 2430 // Entry was deleted by server. We'll make a new one though with a new ID. |
| 2431 Entry dead_fred(&trans, GET_BY_ID, fred_id); |
| 2432 EXPECT_FALSE(dead_fred.good()); |
| 2433 |
| 2434 // Fred is reborn with a local ID. |
| 2435 Entry fred(&trans, GET_BY_ID, bob.Get(PARENT_ID)); |
| 2436 EXPECT_EQ(PSTR("fred"), fred.Get(NON_UNIQUE_NAME)); |
| 2437 EXPECT_EQ(TestIdFactory::root(), fred.Get(PARENT_ID)); |
| 3048 EXPECT_TRUE(fred.Get(IS_UNSYNCED)); | 2438 EXPECT_TRUE(fred.Get(IS_UNSYNCED)); |
| 3049 EXPECT_FALSE(fred.Get(ID).ServerKnows()); | 2439 EXPECT_FALSE(fred.Get(ID).ServerKnows()); |
| 2440 |
| 2441 // Bob needs to update his parent. |
| 3050 EXPECT_TRUE(bob.Get(IS_UNSYNCED)); | 2442 EXPECT_TRUE(bob.Get(IS_UNSYNCED)); |
| 3051 EXPECT_TRUE(bob.Get(PARENT_ID) == fred.Get(ID)); | 2443 EXPECT_TRUE(bob.Get(PARENT_ID) == fred.Get(ID)); |
| 3052 EXPECT_TRUE(fred.Get(PARENT_ID) == root_id_); | 2444 EXPECT_TRUE(fred.Get(PARENT_ID) == root_id_); |
| 3053 EXPECT_FALSE(fred.Get(IS_UNAPPLIED_UPDATE)); | 2445 EXPECT_FALSE(fred.Get(IS_UNAPPLIED_UPDATE)); |
| 3054 EXPECT_FALSE(bob.Get(IS_UNAPPLIED_UPDATE)); | 2446 EXPECT_FALSE(bob.Get(IS_UNAPPLIED_UPDATE)); |
| 3055 } | 2447 } |
| 3056 syncer_events_.clear(); | 2448 syncer_events_.clear(); |
| 3057 } | 2449 } |
| 3058 | 2450 |
| 3059 namespace { | 2451 class FolderMoveDeleteRenameTest : public SyncerTest { |
| 2452 public: |
| 2453 FolderMoveDeleteRenameTest() : move_bob_count_(0), done_(false) {} |
| 3060 | 2454 |
| 3061 int move_bob_count; | 2455 static const int64 bob_id_number = 1; |
| 2456 static const int64 fred_id_number = 2; |
| 3062 | 2457 |
| 3063 bool MoveBobIntoID2(Directory* dir) { | 2458 void MoveBobIntoID2Runner() { |
| 3064 if (--move_bob_count > 0) | 2459 if (!done_) { |
| 2460 done_ = MoveBobIntoID2(); |
| 2461 } |
| 2462 } |
| 2463 |
| 2464 protected: |
| 2465 int move_bob_count_; |
| 2466 bool done_; |
| 2467 |
| 2468 bool MoveBobIntoID2() { |
| 2469 ScopedDirLookup dir(syncdb_.manager(), syncdb_.name()); |
| 2470 CHECK(dir.good()); |
| 2471 |
| 2472 if (--move_bob_count_ > 0) { |
| 2473 return false; |
| 2474 } |
| 2475 |
| 2476 if (move_bob_count_ == 0) { |
| 2477 WriteTransaction trans(dir, UNITTEST, __FILE__, __LINE__); |
| 2478 Entry alice(&trans, GET_BY_ID, |
| 2479 TestIdFactory::FromNumber(fred_id_number)); |
| 2480 CHECK(alice.good()); |
| 2481 CHECK(!alice.Get(IS_DEL)); |
| 2482 MutableEntry bob(&trans, GET_BY_ID, |
| 2483 TestIdFactory::FromNumber(bob_id_number)); |
| 2484 CHECK(bob.good()); |
| 2485 bob.Put(IS_UNSYNCED, true); |
| 2486 bob.Put(PARENT_ID, alice.Get(ID)); |
| 2487 return true; |
| 2488 } |
| 3065 return false; | 2489 return false; |
| 3066 if (move_bob_count == 0) { | |
| 3067 WriteTransaction trans(dir, UNITTEST, __FILE__, __LINE__); | |
| 3068 Entry alice(&trans, GET_BY_ID, TestIdFactory::FromNumber(2)); | |
| 3069 CHECK(alice.good()); | |
| 3070 CHECK(!alice.Get(IS_DEL)); | |
| 3071 MutableEntry bob(&trans, GET_BY_ID, TestIdFactory::FromNumber(1)); | |
| 3072 CHECK(bob.good()); | |
| 3073 bob.Put(IS_UNSYNCED, true); | |
| 3074 bob.Put(PARENT_ID, alice.Get(ID)); | |
| 3075 return true; | |
| 3076 } | 2490 } |
| 3077 return false; | 2491 }; |
| 3078 } | |
| 3079 | 2492 |
| 3080 } // namespace | 2493 TEST_F(FolderMoveDeleteRenameTest, |
| 3081 | |
| 3082 TEST_F(SyncerTest, | |
| 3083 WeMovedSomethingIntoAFolderServerHasDeletedAndWeRenamed) { | 2494 WeMovedSomethingIntoAFolderServerHasDeletedAndWeRenamed) { |
| 3084 ScopedDirLookup dir(syncdb_.manager(), syncdb_.name()); | 2495 ScopedDirLookup dir(syncdb_.manager(), syncdb_.name()); |
| 3085 CHECK(dir.good()); | 2496 CHECK(dir.good()); |
| 3086 mock_server_->AddUpdateDirectory(1, 0, "bob", 1, 10); | 2497 |
| 3087 mock_server_->AddUpdateDirectory(2, 0, "fred", 1, 10); | 2498 const syncable::Id bob_id = TestIdFactory::FromNumber( |
| 2499 FolderMoveDeleteRenameTest::bob_id_number); |
| 2500 const syncable::Id fred_id = TestIdFactory::FromNumber( |
| 2501 FolderMoveDeleteRenameTest::fred_id_number); |
| 2502 |
| 2503 mock_server_->AddUpdateDirectory(bob_id, TestIdFactory::root(), |
| 2504 "bob", 1, 10); |
| 2505 mock_server_->AddUpdateDirectory(fred_id, TestIdFactory::root(), |
| 2506 "fred", 1, 10); |
| 3088 syncer_->SyncShare(); | 2507 syncer_->SyncShare(); |
| 3089 { | 2508 { |
| 3090 WriteTransaction trans(dir, UNITTEST, __FILE__, __LINE__); | 2509 WriteTransaction trans(dir, UNITTEST, __FILE__, __LINE__); |
| 3091 MutableEntry fred(&trans, GET_BY_ID, ids_.FromNumber(2)); | 2510 MutableEntry fred(&trans, GET_BY_ID, fred_id); |
| 3092 ASSERT_TRUE(fred.good()); | 2511 ASSERT_TRUE(fred.good()); |
| 3093 fred.Put(IS_UNSYNCED, true); | 2512 fred.Put(IS_UNSYNCED, true); |
| 3094 fred.Put(NAME, PSTR("Alice")); | 2513 fred.Put(NON_UNIQUE_NAME, PSTR("Alice")); |
| 3095 } | 2514 } |
| 3096 mock_server_->AddUpdateDirectory(2, 0, "fred", 2, 20); | 2515 mock_server_->AddUpdateDirectory(fred_id, TestIdFactory::root(), |
| 2516 "fred", 2, 20); |
| 3097 mock_server_->SetLastUpdateDeleted(); | 2517 mock_server_->SetLastUpdateDeleted(); |
| 3098 mock_server_->set_conflict_all_commits(true); | 2518 mock_server_->set_conflict_all_commits(true); |
| 3099 // This test is a little brittle. We want to move the item into the folder | 2519 // This test is a little brittle. We want to move the item into the folder |
| 3100 // such that we think we're dealing with a simple conflict, but in reality | 2520 // such that we think we're dealing with a simple conflict, but in reality |
| 3101 // it's actually a conflict set. | 2521 // it's actually a conflict set. |
| 3102 move_bob_count = 2; | 2522 move_bob_count_ = 2; |
| 3103 mock_server_->SetMidCommitCallbackFunction(MoveBobIntoID2); | 2523 mock_server_->SetMidCommitCallback( |
| 2524 NewCallback<FolderMoveDeleteRenameTest>(this, |
| 2525 &FolderMoveDeleteRenameTest::MoveBobIntoID2Runner)); |
| 3104 syncer_->SyncShare(); | 2526 syncer_->SyncShare(); |
| 3105 syncer_->SyncShare(); | 2527 syncer_->SyncShare(); |
| 3106 syncer_->SyncShare(); | 2528 syncer_->SyncShare(); |
| 3107 { | 2529 { |
| 3108 ReadTransaction trans(dir, __FILE__, __LINE__); | 2530 ReadTransaction trans(dir, __FILE__, __LINE__); |
| 3109 Entry bob(&trans, GET_BY_ID, ids_.FromNumber(1)); | 2531 Entry bob(&trans, GET_BY_ID, bob_id); |
| 3110 ASSERT_TRUE(bob.good()); | 2532 ASSERT_TRUE(bob.good()); |
| 3111 Entry alice(&trans, GET_BY_PATH, PSTR("Alice")); | 2533 |
| 2534 // Old entry is dead |
| 2535 Entry dead_fred(&trans, GET_BY_ID, fred_id); |
| 2536 EXPECT_FALSE(dead_fred.good()); |
| 2537 |
| 2538 // New ID is created to fill parent folder, named correctly |
| 2539 Entry alice(&trans, GET_BY_ID, bob.Get(PARENT_ID)); |
| 3112 ASSERT_TRUE(alice.good()); | 2540 ASSERT_TRUE(alice.good()); |
| 2541 EXPECT_EQ(PSTR("Alice"), alice.Get(NON_UNIQUE_NAME)); |
| 3113 EXPECT_TRUE(alice.Get(IS_UNSYNCED)); | 2542 EXPECT_TRUE(alice.Get(IS_UNSYNCED)); |
| 3114 EXPECT_FALSE(alice.Get(ID).ServerKnows()); | 2543 EXPECT_FALSE(alice.Get(ID).ServerKnows()); |
| 3115 EXPECT_TRUE(bob.Get(IS_UNSYNCED)); | 2544 EXPECT_TRUE(bob.Get(IS_UNSYNCED)); |
| 3116 EXPECT_TRUE(bob.Get(PARENT_ID) == alice.Get(ID)); | 2545 EXPECT_TRUE(bob.Get(PARENT_ID) == alice.Get(ID)); |
| 3117 EXPECT_TRUE(alice.Get(PARENT_ID) == root_id_); | 2546 EXPECT_TRUE(alice.Get(PARENT_ID) == root_id_); |
| 3118 EXPECT_FALSE(alice.Get(IS_UNAPPLIED_UPDATE)); | 2547 EXPECT_FALSE(alice.Get(IS_UNAPPLIED_UPDATE)); |
| 3119 EXPECT_FALSE(bob.Get(IS_UNAPPLIED_UPDATE)); | 2548 EXPECT_FALSE(bob.Get(IS_UNAPPLIED_UPDATE)); |
| 3120 } | 2549 } |
| 3121 syncer_events_.clear(); | 2550 syncer_events_.clear(); |
| 3122 } | 2551 } |
| 3123 | 2552 |
| 3124 | 2553 |
| 3125 TEST_F(SyncerTest, | 2554 TEST_F(SyncerTest, |
| 3126 WeMovedADirIntoAndCreatedAnEntryInAFolderServerHasDeleted) { | 2555 WeMovedADirIntoAndCreatedAnEntryInAFolderServerHasDeleted) { |
| 3127 ScopedDirLookup dir(syncdb_.manager(), syncdb_.name()); | 2556 ScopedDirLookup dir(syncdb_.manager(), syncdb_.name()); |
| 3128 CHECK(dir.good()); | 2557 CHECK(dir.good()); |
| 3129 mock_server_->AddUpdateDirectory(1, 0, "bob", 1, 10); | 2558 |
| 3130 mock_server_->AddUpdateDirectory(2, 0, "fred", 1, 10); | 2559 syncable::Id bob_id = ids_.NewServerId(); |
| 2560 syncable::Id fred_id = ids_.NewServerId(); |
| 2561 |
| 2562 mock_server_->AddUpdateDirectory(bob_id, TestIdFactory::root(), |
| 2563 "bob", 1, 10); |
| 2564 mock_server_->AddUpdateDirectory(fred_id, TestIdFactory::root(), |
| 2565 "fred", 1, 10); |
| 3131 syncer_->SyncShare(); | 2566 syncer_->SyncShare(); |
| 3132 syncable::Id new_item_id; | 2567 syncable::Id new_item_id; |
| 3133 { | 2568 { |
| 3134 WriteTransaction trans(dir, UNITTEST, __FILE__, __LINE__); | 2569 WriteTransaction trans(dir, UNITTEST, __FILE__, __LINE__); |
| 3135 MutableEntry bob(&trans, GET_BY_ID, ids_.FromNumber(1)); | 2570 MutableEntry bob(&trans, GET_BY_ID, bob_id); |
| 3136 ASSERT_TRUE(bob.good()); | 2571 ASSERT_TRUE(bob.good()); |
| 3137 bob.Put(IS_UNSYNCED, true); | 2572 bob.Put(IS_UNSYNCED, true); |
| 3138 bob.Put(PARENT_ID, ids_.FromNumber(2)); | 2573 bob.Put(PARENT_ID, fred_id); |
| 3139 MutableEntry new_item(&trans, CREATE, ids_.FromNumber(2), PSTR("new_item")); | 2574 MutableEntry new_item(&trans, CREATE, fred_id, PSTR("new_item")); |
| 3140 WriteTestDataToEntry(&trans, &new_item); | 2575 WriteTestDataToEntry(&trans, &new_item); |
| 3141 new_item_id = new_item.Get(ID); | 2576 new_item_id = new_item.Get(ID); |
| 3142 } | 2577 } |
| 3143 mock_server_->AddUpdateDirectory(2, 0, "fred", 2, 20); | 2578 mock_server_->AddUpdateDirectory(fred_id, TestIdFactory::root(), |
| 2579 "fred", 2, 20); |
| 3144 mock_server_->SetLastUpdateDeleted(); | 2580 mock_server_->SetLastUpdateDeleted(); |
| 3145 mock_server_->set_conflict_all_commits(true); | 2581 mock_server_->set_conflict_all_commits(true); |
| 3146 syncer_->SyncShare(); | 2582 syncer_->SyncShare(); |
| 3147 syncer_->SyncShare(); | 2583 syncer_->SyncShare(); |
| 3148 { | 2584 { |
| 3149 ReadTransaction trans(dir, __FILE__, __LINE__); | 2585 ReadTransaction trans(dir, __FILE__, __LINE__); |
| 3150 Entry bob(&trans, GET_BY_ID, ids_.FromNumber(1)); | 2586 |
| 2587 Entry bob(&trans, GET_BY_ID, bob_id); |
| 3151 ASSERT_TRUE(bob.good()); | 2588 ASSERT_TRUE(bob.good()); |
| 3152 Entry fred(&trans, GET_BY_PATH, PSTR("fred")); | 2589 EXPECT_TRUE(bob.Get(IS_UNSYNCED)); |
| 2590 EXPECT_FALSE(bob.Get(IS_UNAPPLIED_UPDATE)); |
| 2591 EXPECT_NE(bob.Get(PARENT_ID), fred_id); |
| 2592 |
| 2593 // Was recreated. Old one shouldn't exist. |
| 2594 Entry dead_fred(&trans, GET_BY_ID, fred_id); |
| 2595 EXPECT_FALSE(dead_fred.good()); |
| 2596 |
| 2597 Entry fred(&trans, GET_BY_ID, bob.Get(PARENT_ID)); |
| 3153 ASSERT_TRUE(fred.good()); | 2598 ASSERT_TRUE(fred.good()); |
| 3154 PathChar path[] = {'f', 'r', 'e', 'd', *kPathSeparator, | |
| 3155 'n', 'e', 'w', '_', 'i', 't', 'e', 'm', 0}; | |
| 3156 Entry new_item(&trans, GET_BY_PATH, path); | |
| 3157 EXPECT_TRUE(new_item.good()); | |
| 3158 EXPECT_TRUE(fred.Get(IS_UNSYNCED)); | 2599 EXPECT_TRUE(fred.Get(IS_UNSYNCED)); |
| 3159 EXPECT_FALSE(fred.Get(ID).ServerKnows()); | 2600 EXPECT_FALSE(fred.Get(ID).ServerKnows()); |
| 3160 EXPECT_TRUE(bob.Get(IS_UNSYNCED)); | 2601 EXPECT_EQ(PSTR("fred"), fred.Get(NON_UNIQUE_NAME)); |
| 3161 EXPECT_TRUE(bob.Get(PARENT_ID) == fred.Get(ID)); | 2602 EXPECT_FALSE(fred.Get(IS_UNAPPLIED_UPDATE)); |
| 3162 EXPECT_TRUE(fred.Get(PARENT_ID) == root_id_); | 2603 EXPECT_TRUE(fred.Get(PARENT_ID) == root_id_); |
| 3163 EXPECT_FALSE(fred.Get(IS_UNAPPLIED_UPDATE)); | 2604 |
| 3164 EXPECT_FALSE(bob.Get(IS_UNAPPLIED_UPDATE)); | 2605 Entry new_item(&trans, GET_BY_ID, new_item_id); |
| 2606 ASSERT_TRUE(new_item.good()); |
| 2607 EXPECT_EQ(new_item.Get(PARENT_ID), fred.Get(ID)); |
| 3165 } | 2608 } |
| 3166 syncer_events_.clear(); | 2609 syncer_events_.clear(); |
| 3167 } | 2610 } |
| 3168 | 2611 |
| 3169 TEST_F(SyncerTest, ServerMovedSomethingIntoAFolderWeHaveDeleted) { | 2612 TEST_F(SyncerTest, ServerMovedSomethingIntoAFolderWeHaveDeleted) { |
| 3170 ScopedDirLookup dir(syncdb_.manager(), syncdb_.name()); | 2613 ScopedDirLookup dir(syncdb_.manager(), syncdb_.name()); |
| 3171 CHECK(dir.good()); | 2614 CHECK(dir.good()); |
| 3172 mock_server_->AddUpdateDirectory(1, 0, "bob", 1, 10); | 2615 mock_server_->AddUpdateDirectory(1, 0, "bob", 1, 10); |
| 3173 mock_server_->AddUpdateDirectory(2, 0, "fred", 1, 10); | 2616 mock_server_->AddUpdateDirectory(2, 0, "fred", 1, 10); |
| 3174 LoopSyncShare(syncer_); | 2617 LoopSyncShare(syncer_); |
| (...skipping 177 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3352 EXPECT_EQ(bob.Get(PARENT_ID), susan.Get(ID)); | 2795 EXPECT_EQ(bob.Get(PARENT_ID), susan.Get(ID)); |
| 3353 EXPECT_EQ(susan.Get(PARENT_ID), root_id_); | 2796 EXPECT_EQ(susan.Get(PARENT_ID), root_id_); |
| 3354 EXPECT_FALSE(susan.Get(IS_UNAPPLIED_UPDATE)); | 2797 EXPECT_FALSE(susan.Get(IS_UNAPPLIED_UPDATE)); |
| 3355 EXPECT_FALSE(fred.Get(IS_UNAPPLIED_UPDATE)); | 2798 EXPECT_FALSE(fred.Get(IS_UNAPPLIED_UPDATE)); |
| 3356 EXPECT_FALSE(bob.Get(IS_UNAPPLIED_UPDATE)); | 2799 EXPECT_FALSE(bob.Get(IS_UNAPPLIED_UPDATE)); |
| 3357 EXPECT_FALSE(joe.Get(IS_UNAPPLIED_UPDATE)); | 2800 EXPECT_FALSE(joe.Get(IS_UNAPPLIED_UPDATE)); |
| 3358 } | 2801 } |
| 3359 syncer_events_.clear(); | 2802 syncer_events_.clear(); |
| 3360 } | 2803 } |
| 3361 | 2804 |
| 3362 namespace { | |
| 3363 | 2805 |
| 3364 int countown_till_delete = 0; | 2806 class SusanDeletingTest : public SyncerTest { |
| 2807 public: |
| 2808 SusanDeletingTest() : countdown_till_delete_(0) {} |
| 3365 | 2809 |
| 3366 void DeleteSusanInRoot(Directory* dir) { | 2810 static const int64 susan_int_id_ = 4; |
| 3367 ASSERT_GT(countown_till_delete, 0); | |
| 3368 if (0 != --countown_till_delete) | |
| 3369 return; | |
| 3370 WriteTransaction trans(dir, UNITTEST, __FILE__, __LINE__); | |
| 3371 MutableEntry susan(&trans, GET_BY_PATH, PSTR("susan")); | |
| 3372 Directory::ChildHandles children; | |
| 3373 dir->GetChildHandles(&trans, susan.Get(ID), &children); | |
| 3374 ASSERT_TRUE(0 == children.size()); | |
| 3375 susan.Put(IS_DEL, true); | |
| 3376 susan.Put(IS_UNSYNCED, true); | |
| 3377 } | |
| 3378 | 2811 |
| 3379 } // namespace | 2812 void DeleteSusanInRoot() { |
| 2813 ScopedDirLookup dir(syncdb_.manager(), syncdb_.name()); |
| 2814 ASSERT_TRUE(dir.good()); |
| 3380 | 2815 |
| 3381 TEST_F(SyncerTest, NewServerItemInAFolderHierarchyWeHaveDeleted3) { | 2816 const syncable::Id susan_id = TestIdFactory::FromNumber(susan_int_id_); |
| 2817 ASSERT_GT(countdown_till_delete_, 0); |
| 2818 if (0 != --countdown_till_delete_) |
| 2819 return; |
| 2820 WriteTransaction trans(dir, UNITTEST, __FILE__, __LINE__); |
| 2821 MutableEntry susan(&trans, GET_BY_ID, susan_id); |
| 2822 Directory::ChildHandles children; |
| 2823 dir->GetChildHandles(&trans, susan.Get(ID), &children); |
| 2824 ASSERT_TRUE(0 == children.size()); |
| 2825 susan.Put(IS_DEL, true); |
| 2826 susan.Put(IS_UNSYNCED, true); |
| 2827 } |
| 2828 |
| 2829 protected: |
| 2830 int countdown_till_delete_; |
| 2831 }; |
| 2832 |
| 2833 TEST_F(SusanDeletingTest, |
| 2834 NewServerItemInAFolderHierarchyWeHaveDeleted3) { |
| 3382 // Same as 2, except we deleted the folder the set is in between set building | 2835 // Same as 2, except we deleted the folder the set is in between set building |
| 3383 // and conflict resolution. | 2836 // and conflict resolution. |
| 3384 ScopedDirLookup dir(syncdb_.manager(), syncdb_.name()); | 2837 ScopedDirLookup dir(syncdb_.manager(), syncdb_.name()); |
| 3385 CHECK(dir.good()); | 2838 CHECK(dir.good()); |
| 3386 mock_server_->AddUpdateDirectory(4, 0, "susan", 1, 10); | 2839 |
| 3387 mock_server_->AddUpdateDirectory(1, 4, "bob", 1, 10); | 2840 const syncable::Id bob_id = TestIdFactory::FromNumber(1); |
| 3388 mock_server_->AddUpdateDirectory(2, 1, "joe", 1, 10); | 2841 const syncable::Id joe_id = TestIdFactory::FromNumber(2); |
| 2842 const syncable::Id fred_id = TestIdFactory::FromNumber(3); |
| 2843 const syncable::Id susan_id = TestIdFactory::FromNumber(susan_int_id_); |
| 2844 |
| 2845 mock_server_->AddUpdateDirectory(susan_id, TestIdFactory::root(), |
| 2846 "susan", 1, 10); |
| 2847 mock_server_->AddUpdateDirectory(bob_id, susan_id, "bob", 1, 10); |
| 2848 mock_server_->AddUpdateDirectory(joe_id, bob_id, "joe", 1, 10); |
| 3389 LoopSyncShare(syncer_); | 2849 LoopSyncShare(syncer_); |
| 3390 { | 2850 { |
| 3391 WriteTransaction trans(dir, UNITTEST, __FILE__, __LINE__); | 2851 WriteTransaction trans(dir, UNITTEST, __FILE__, __LINE__); |
| 3392 MutableEntry bob(&trans, GET_BY_ID, ids_.FromNumber(1)); | 2852 MutableEntry bob(&trans, GET_BY_ID, bob_id); |
| 3393 ASSERT_TRUE(bob.good()); | 2853 ASSERT_TRUE(bob.good()); |
| 3394 bob.Put(IS_UNSYNCED, true); | 2854 bob.Put(IS_UNSYNCED, true); |
| 3395 bob.Put(IS_DEL, true); | 2855 bob.Put(IS_DEL, true); |
| 3396 MutableEntry joe(&trans, GET_BY_ID, ids_.FromNumber(2)); | 2856 |
| 2857 MutableEntry joe(&trans, GET_BY_ID, joe_id); |
| 3397 ASSERT_TRUE(joe.good()); | 2858 ASSERT_TRUE(joe.good()); |
| 3398 joe.Put(IS_UNSYNCED, true); | 2859 joe.Put(IS_UNSYNCED, true); |
| 3399 joe.Put(IS_DEL, true); | 2860 joe.Put(IS_DEL, true); |
| 3400 } | 2861 } |
| 3401 mock_server_->AddUpdateDirectory(3, 2, "fred", 2, 20); | 2862 mock_server_->AddUpdateDirectory(fred_id, joe_id, "fred", 2, 20); |
| 3402 mock_server_->set_conflict_all_commits(true); | 2863 mock_server_->set_conflict_all_commits(true); |
| 3403 countown_till_delete = 2; | 2864 countdown_till_delete_ = 2; |
| 3404 syncer_->pre_conflict_resolution_function_ = DeleteSusanInRoot; | 2865 syncer_->pre_conflict_resolution_closure_ = |
| 2866 NewCallback<SusanDeletingTest>(this, |
| 2867 &SusanDeletingTest::DeleteSusanInRoot); |
| 3405 syncer_->SyncShare(); | 2868 syncer_->SyncShare(); |
| 3406 syncer_->SyncShare(); | 2869 syncer_->SyncShare(); |
| 3407 { | 2870 { |
| 3408 ReadTransaction trans(dir, __FILE__, __LINE__); | 2871 ReadTransaction trans(dir, __FILE__, __LINE__); |
| 3409 Entry bob(&trans, GET_BY_ID, ids_.FromNumber(1)); | 2872 Entry bob(&trans, GET_BY_ID, bob_id); |
| 3410 ASSERT_TRUE(bob.good()); | 2873 ASSERT_TRUE(bob.good()); |
| 3411 Entry joe(&trans, GET_BY_ID, ids_.FromNumber(2)); | 2874 Entry joe(&trans, GET_BY_ID, joe_id); |
| 3412 ASSERT_TRUE(joe.good()); | 2875 ASSERT_TRUE(joe.good()); |
| 3413 Entry fred(&trans, GET_BY_ID, ids_.FromNumber(3)); | 2876 Entry fred(&trans, GET_BY_ID, fred_id); |
| 3414 ASSERT_TRUE(fred.good()); | 2877 ASSERT_TRUE(fred.good()); |
| 3415 Entry susan(&trans, GET_BY_ID, ids_.FromNumber(4)); | 2878 Entry susan(&trans, GET_BY_ID, susan_id); |
| 3416 ASSERT_TRUE(susan.good()); | 2879 ASSERT_TRUE(susan.good()); |
| 3417 EXPECT_FALSE(susan.Get(IS_UNAPPLIED_UPDATE)); | 2880 EXPECT_FALSE(susan.Get(IS_UNAPPLIED_UPDATE)); |
| 3418 EXPECT_TRUE(fred.Get(IS_UNAPPLIED_UPDATE)); | 2881 EXPECT_TRUE(fred.Get(IS_UNAPPLIED_UPDATE)); |
| 3419 EXPECT_FALSE(bob.Get(IS_UNAPPLIED_UPDATE)); | 2882 EXPECT_FALSE(bob.Get(IS_UNAPPLIED_UPDATE)); |
| 3420 EXPECT_FALSE(joe.Get(IS_UNAPPLIED_UPDATE)); | 2883 EXPECT_FALSE(joe.Get(IS_UNAPPLIED_UPDATE)); |
| 3421 EXPECT_TRUE(susan.Get(IS_UNSYNCED)); | 2884 EXPECT_TRUE(susan.Get(IS_UNSYNCED)); |
| 3422 EXPECT_FALSE(fred.Get(IS_UNSYNCED)); | 2885 EXPECT_FALSE(fred.Get(IS_UNSYNCED)); |
| 3423 EXPECT_TRUE(bob.Get(IS_UNSYNCED)); | 2886 EXPECT_TRUE(bob.Get(IS_UNSYNCED)); |
| 3424 EXPECT_TRUE(joe.Get(IS_UNSYNCED)); | 2887 EXPECT_TRUE(joe.Get(IS_UNSYNCED)); |
| 3425 } | 2888 } |
| 3426 EXPECT_TRUE(0 == countown_till_delete); | 2889 EXPECT_TRUE(0 == countdown_till_delete_); |
| 3427 syncer_->pre_conflict_resolution_function_ = 0; | 2890 syncer_->pre_conflict_resolution_closure_ = NULL; |
| 3428 LoopSyncShare(syncer_); | 2891 LoopSyncShare(syncer_); |
| 3429 LoopSyncShare(syncer_); | 2892 LoopSyncShare(syncer_); |
| 3430 { | 2893 { |
| 3431 ReadTransaction trans(dir, __FILE__, __LINE__); | 2894 ReadTransaction trans(dir, __FILE__, __LINE__); |
| 3432 Entry bob(&trans, GET_BY_ID, ids_.FromNumber(1)); | 2895 Entry bob(&trans, GET_BY_ID, bob_id); |
| 3433 ASSERT_TRUE(bob.good()); | 2896 ASSERT_TRUE(bob.good()); |
| 3434 Entry joe(&trans, GET_BY_ID, ids_.FromNumber(2)); | 2897 Entry joe(&trans, GET_BY_ID, joe_id); |
| 3435 ASSERT_TRUE(joe.good()); | 2898 ASSERT_TRUE(joe.good()); |
| 3436 Entry fred(&trans, GET_BY_ID, ids_.FromNumber(3)); | 2899 Entry fred(&trans, GET_BY_ID, fred_id); |
| 3437 ASSERT_TRUE(fred.good()); | 2900 ASSERT_TRUE(fred.good()); |
| 3438 Entry susan(&trans, GET_BY_ID, ids_.FromNumber(4)); | 2901 Entry susan(&trans, GET_BY_ID, susan_id); |
| 3439 ASSERT_TRUE(susan.good()); | 2902 ASSERT_TRUE(susan.good()); |
| 3440 EXPECT_TRUE(susan.Get(IS_UNSYNCED)); | 2903 EXPECT_TRUE(susan.Get(IS_UNSYNCED)); |
| 3441 EXPECT_FALSE(fred.Get(IS_UNSYNCED)); | 2904 EXPECT_FALSE(fred.Get(IS_UNSYNCED)); |
| 3442 EXPECT_TRUE(bob.Get(IS_UNSYNCED)); | 2905 EXPECT_TRUE(bob.Get(IS_UNSYNCED)); |
| 3443 EXPECT_TRUE(joe.Get(IS_UNSYNCED)); | 2906 EXPECT_TRUE(joe.Get(IS_UNSYNCED)); |
| 3444 EXPECT_TRUE(fred.Get(PARENT_ID) == joe.Get(ID)); | 2907 EXPECT_TRUE(fred.Get(PARENT_ID) == joe.Get(ID)); |
| 3445 EXPECT_TRUE(joe.Get(PARENT_ID) == bob.Get(ID)); | 2908 EXPECT_TRUE(joe.Get(PARENT_ID) == bob.Get(ID)); |
| 3446 EXPECT_TRUE(bob.Get(PARENT_ID) == susan.Get(ID)); | 2909 EXPECT_TRUE(bob.Get(PARENT_ID) == susan.Get(ID)); |
| 3447 EXPECT_TRUE(susan.Get(PARENT_ID) == root_id_); | 2910 EXPECT_TRUE(susan.Get(PARENT_ID) == root_id_); |
| 3448 EXPECT_FALSE(susan.Get(IS_UNAPPLIED_UPDATE)); | 2911 EXPECT_FALSE(susan.Get(IS_UNAPPLIED_UPDATE)); |
| 3449 EXPECT_FALSE(fred.Get(IS_UNAPPLIED_UPDATE)); | 2912 EXPECT_FALSE(fred.Get(IS_UNAPPLIED_UPDATE)); |
| 3450 EXPECT_FALSE(bob.Get(IS_UNAPPLIED_UPDATE)); | 2913 EXPECT_FALSE(bob.Get(IS_UNAPPLIED_UPDATE)); |
| 3451 EXPECT_FALSE(joe.Get(IS_UNAPPLIED_UPDATE)); | 2914 EXPECT_FALSE(joe.Get(IS_UNAPPLIED_UPDATE)); |
| 3452 } | 2915 } |
| 3453 syncer_events_.clear(); | 2916 syncer_events_.clear(); |
| 3454 } | 2917 } |
| 3455 | 2918 |
| 3456 TEST_F(SyncerTest, WeMovedSomethingIntoAFolderHierarchyServerHasDeleted) { | 2919 TEST_F(SyncerTest, WeMovedSomethingIntoAFolderHierarchyServerHasDeleted) { |
| 3457 ScopedDirLookup dir(syncdb_.manager(), syncdb_.name()); | 2920 ScopedDirLookup dir(syncdb_.manager(), syncdb_.name()); |
| 3458 CHECK(dir.good()); | 2921 CHECK(dir.good()); |
| 3459 mock_server_->AddUpdateDirectory(1, 0, "bob", 1, 10); | 2922 |
| 3460 mock_server_->AddUpdateDirectory(2, 0, "fred", 1, 10); | 2923 const syncable::Id bob_id = ids_.NewServerId(); |
| 3461 mock_server_->AddUpdateDirectory(3, 2, "alice", 1, 10); | 2924 const syncable::Id fred_id = ids_.NewServerId(); |
| 2925 const syncable::Id alice_id = ids_.NewServerId(); |
| 2926 |
| 2927 mock_server_->AddUpdateDirectory(bob_id, TestIdFactory::root(), |
| 2928 "bob", 1, 10); |
| 2929 mock_server_->AddUpdateDirectory(fred_id, TestIdFactory::root(), |
| 2930 "fred", 1, 10); |
| 2931 mock_server_->AddUpdateDirectory(alice_id, fred_id, "alice", 1, 10); |
| 3462 syncer_->SyncShare(); | 2932 syncer_->SyncShare(); |
| 3463 { | 2933 { |
| 3464 WriteTransaction trans(dir, UNITTEST, __FILE__, __LINE__); | 2934 WriteTransaction trans(dir, UNITTEST, __FILE__, __LINE__); |
| 3465 MutableEntry bob(&trans, GET_BY_ID, ids_.FromNumber(1)); | 2935 MutableEntry bob(&trans, GET_BY_ID, bob_id); |
| 3466 ASSERT_TRUE(bob.good()); | 2936 ASSERT_TRUE(bob.good()); |
| 3467 bob.Put(IS_UNSYNCED, true); | 2937 bob.Put(IS_UNSYNCED, true); |
| 3468 bob.Put(PARENT_ID, ids_.FromNumber(3)); // Move into alice. | 2938 bob.Put(PARENT_ID, alice_id); // Move into alice. |
| 3469 } | 2939 } |
| 3470 mock_server_->AddUpdateDirectory(2, 0, "fred", 2, 20); | 2940 mock_server_->AddUpdateDirectory(fred_id, TestIdFactory::root(), |
| 2941 "fred", 2, 20); |
| 3471 mock_server_->SetLastUpdateDeleted(); | 2942 mock_server_->SetLastUpdateDeleted(); |
| 3472 mock_server_->AddUpdateDirectory(3, 0, "alice", 2, 20); | 2943 mock_server_->AddUpdateDirectory(alice_id, TestIdFactory::root(), |
| 2944 "alice", 2, 20); |
| 3473 mock_server_->SetLastUpdateDeleted(); | 2945 mock_server_->SetLastUpdateDeleted(); |
| 3474 mock_server_->set_conflict_all_commits(true); | 2946 mock_server_->set_conflict_all_commits(true); |
| 3475 syncer_->SyncShare(); | 2947 syncer_->SyncShare(); |
| 3476 syncer_->SyncShare(); | 2948 syncer_->SyncShare(); |
| 3477 { | 2949 { |
| 2950 // Bob is the entry at the bottom of the tree. |
| 2951 // The tree should be regenerated and old IDs removed. |
| 3478 ReadTransaction trans(dir, __FILE__, __LINE__); | 2952 ReadTransaction trans(dir, __FILE__, __LINE__); |
| 3479 Entry bob(&trans, GET_BY_ID, ids_.FromNumber(1)); | 2953 Entry bob(&trans, GET_BY_ID, bob_id); |
| 3480 ASSERT_TRUE(bob.good()); | 2954 ASSERT_TRUE(bob.good()); |
| 3481 Entry fred(&trans, GET_BY_PATH, PSTR("fred")); | 2955 EXPECT_FALSE(bob.Get(IS_UNAPPLIED_UPDATE)); |
| 2956 EXPECT_TRUE(bob.Get(IS_UNSYNCED)); |
| 2957 |
| 2958 // Old one should be deleted, but new one should have been made. |
| 2959 Entry dead_alice(&trans, GET_BY_ID, alice_id); |
| 2960 EXPECT_FALSE(dead_alice.good()); |
| 2961 EXPECT_NE(bob.Get(PARENT_ID), alice_id); |
| 2962 |
| 2963 // Newly born alice |
| 2964 Entry alice(&trans, GET_BY_ID, bob.Get(PARENT_ID)); |
| 2965 ASSERT_TRUE(alice.good()); |
| 2966 EXPECT_FALSE(alice.Get(IS_UNAPPLIED_UPDATE)); |
| 2967 EXPECT_TRUE(alice.Get(IS_UNSYNCED)); |
| 2968 EXPECT_FALSE(alice.Get(ID).ServerKnows()); |
| 2969 EXPECT_TRUE(alice.Get(NON_UNIQUE_NAME) == PSTR("alice")); |
| 2970 |
| 2971 // Alice needs a parent as well. Old parent should have been erased. |
| 2972 Entry dead_fred(&trans, GET_BY_ID, fred_id); |
| 2973 EXPECT_FALSE(dead_fred.good()); |
| 2974 EXPECT_NE(alice.Get(PARENT_ID), fred_id); |
| 2975 |
| 2976 Entry fred(&trans, GET_BY_ID, alice.Get(PARENT_ID)); |
| 3482 ASSERT_TRUE(fred.good()); | 2977 ASSERT_TRUE(fred.good()); |
| 3483 PathChar path[] = {'f', 'r', 'e', 'd', *kPathSeparator, | 2978 EXPECT_EQ(fred.Get(PARENT_ID), TestIdFactory::root()); |
| 3484 'a', 'l', 'i', 'c', 'e', 0}; | |
| 3485 Entry alice(&trans, GET_BY_PATH, path); | |
| 3486 ASSERT_TRUE(alice.good()); | |
| 3487 EXPECT_TRUE(fred.Get(IS_UNSYNCED)); | 2979 EXPECT_TRUE(fred.Get(IS_UNSYNCED)); |
| 3488 EXPECT_TRUE(alice.Get(IS_UNSYNCED)); | |
| 3489 EXPECT_TRUE(bob.Get(IS_UNSYNCED)); | |
| 3490 EXPECT_FALSE(fred.Get(ID).ServerKnows()); | 2980 EXPECT_FALSE(fred.Get(ID).ServerKnows()); |
| 3491 EXPECT_FALSE(alice.Get(ID).ServerKnows()); | |
| 3492 EXPECT_TRUE(alice.Get(PARENT_ID) == fred.Get(ID)); | |
| 3493 EXPECT_TRUE(bob.Get(PARENT_ID) == alice.Get(ID)); | |
| 3494 EXPECT_TRUE(fred.Get(PARENT_ID) == root_id_); | |
| 3495 EXPECT_FALSE(fred.Get(IS_UNAPPLIED_UPDATE)); | 2981 EXPECT_FALSE(fred.Get(IS_UNAPPLIED_UPDATE)); |
| 3496 EXPECT_FALSE(bob.Get(IS_UNAPPLIED_UPDATE)); | 2982 EXPECT_TRUE(fred.Get(NON_UNIQUE_NAME) == PSTR("fred")); |
| 3497 EXPECT_FALSE(alice.Get(IS_UNAPPLIED_UPDATE)); | |
| 3498 } | 2983 } |
| 3499 syncer_events_.clear(); | 2984 syncer_events_.clear(); |
| 3500 } | 2985 } |
| 3501 | 2986 |
| 3502 TEST_F(SyncerTest, WeMovedSomethingIntoAFolderHierarchyServerHasDeleted2) { | 2987 TEST_F(SyncerTest, WeMovedSomethingIntoAFolderHierarchyServerHasDeleted2) { |
| 3503 // The difference here is that the hierarchy's not in the root. We have | 2988 // The difference here is that the hierarchy is not in the root. We have |
| 3504 // another entry that shouldn't be touched. | 2989 // another entry that shouldn't be touched. |
| 3505 ScopedDirLookup dir(syncdb_.manager(), syncdb_.name()); | 2990 ScopedDirLookup dir(syncdb_.manager(), syncdb_.name()); |
| 3506 CHECK(dir.good()); | 2991 CHECK(dir.good()); |
| 3507 mock_server_->AddUpdateDirectory(1, 0, "bob", 1, 10); | 2992 |
| 3508 mock_server_->AddUpdateDirectory(4, 0, "susan", 1, 10); | 2993 const syncable::Id bob_id = ids_.NewServerId(); |
| 3509 mock_server_->AddUpdateDirectory(2, 4, "fred", 1, 10); | 2994 const syncable::Id fred_id = ids_.NewServerId(); |
| 3510 mock_server_->AddUpdateDirectory(3, 2, "alice", 1, 10); | 2995 const syncable::Id alice_id = ids_.NewServerId(); |
| 2996 const syncable::Id susan_id = ids_.NewServerId(); |
| 2997 |
| 2998 mock_server_->AddUpdateDirectory(bob_id, TestIdFactory::root(), |
| 2999 "bob", 1, 10); |
| 3000 mock_server_->AddUpdateDirectory(susan_id, TestIdFactory::root(), |
| 3001 "susan", 1, 10); |
| 3002 mock_server_->AddUpdateDirectory(fred_id, susan_id, "fred", 1, 10); |
| 3003 mock_server_->AddUpdateDirectory(alice_id, fred_id, "alice", 1, 10); |
| 3511 syncer_->SyncShare(); | 3004 syncer_->SyncShare(); |
| 3512 { | 3005 { |
| 3513 WriteTransaction trans(dir, UNITTEST, __FILE__, __LINE__); | 3006 WriteTransaction trans(dir, UNITTEST, __FILE__, __LINE__); |
| 3514 MutableEntry bob(&trans, GET_BY_ID, ids_.FromNumber(1)); | 3007 MutableEntry bob(&trans, GET_BY_ID, bob_id); |
| 3515 ASSERT_TRUE(bob.good()); | 3008 ASSERT_TRUE(bob.good()); |
| 3516 bob.Put(IS_UNSYNCED, true); | 3009 bob.Put(IS_UNSYNCED, true); |
| 3517 bob.Put(PARENT_ID, ids_.FromNumber(3)); // Move into alice. | 3010 bob.Put(PARENT_ID, alice_id); // Move into alice. |
| 3518 } | 3011 } |
| 3519 mock_server_->AddUpdateDirectory(2, 0, "fred", 2, 20); | 3012 mock_server_->AddUpdateDirectory(fred_id, TestIdFactory::root(), |
| 3013 "fred", 2, 20); |
| 3520 mock_server_->SetLastUpdateDeleted(); | 3014 mock_server_->SetLastUpdateDeleted(); |
| 3521 mock_server_->AddUpdateDirectory(3, 0, "alice", 2, 20); | 3015 mock_server_->AddUpdateDirectory(alice_id, TestIdFactory::root(), |
| 3016 "alice", 2, 20); |
| 3522 mock_server_->SetLastUpdateDeleted(); | 3017 mock_server_->SetLastUpdateDeleted(); |
| 3523 mock_server_->set_conflict_all_commits(true); | 3018 mock_server_->set_conflict_all_commits(true); |
| 3524 syncer_->SyncShare(); | 3019 syncer_->SyncShare(); |
| 3525 syncer_->SyncShare(); | 3020 syncer_->SyncShare(); |
| 3526 { | 3021 { |
| 3022 // Root |
| 3023 // |- Susan |
| 3024 // |- Fred |
| 3025 // |- Alice |
| 3026 // |- Bob |
| 3027 |
| 3527 ReadTransaction trans(dir, __FILE__, __LINE__); | 3028 ReadTransaction trans(dir, __FILE__, __LINE__); |
| 3528 Entry bob(&trans, GET_BY_ID, ids_.FromNumber(1)); | 3029 Entry bob(&trans, GET_BY_ID, bob_id); |
| 3529 ASSERT_TRUE(bob.good()); | 3030 ASSERT_TRUE(bob.good()); |
| 3530 PathChar path[] = {'s', 'u', 's', 'a', 'n', *kPathSeparator, | 3031 EXPECT_FALSE(bob.Get(IS_UNAPPLIED_UPDATE)); |
| 3531 'f', 'r', 'e', 'd', 0}; | 3032 EXPECT_TRUE(bob.Get(IS_UNSYNCED)); // Parent changed |
| 3532 Entry fred(&trans, GET_BY_PATH, path); | 3033 EXPECT_NE(bob.Get(PARENT_ID), alice_id); |
| 3533 ASSERT_TRUE(fred.good()); | 3034 |
| 3534 PathChar path2[] = {'s', 'u', 's', 'a', 'n', *kPathSeparator, | 3035 // New one was born, this is the old one |
| 3535 'f', 'r', 'e', 'd', *kPathSeparator, | 3036 Entry dead_alice(&trans, GET_BY_ID, alice_id); |
| 3536 'a', 'l', 'i', 'c', 'e', 0}; | 3037 EXPECT_FALSE(dead_alice.good()); |
| 3537 Entry alice(&trans, GET_BY_PATH, path2); | 3038 |
| 3538 ASSERT_TRUE(alice.good()); | 3039 // Newly born |
| 3539 Entry susan(&trans, GET_BY_ID, ids_.FromNumber(4)); | 3040 Entry alice(&trans, GET_BY_ID, bob.Get(PARENT_ID)); |
| 3540 ASSERT_TRUE(susan.good()); | 3041 EXPECT_TRUE(alice.Get(IS_UNSYNCED)); |
| 3541 Entry susan_by_path(&trans, GET_BY_PATH, PSTR("susan")); | 3042 EXPECT_FALSE(alice.Get(IS_UNAPPLIED_UPDATE)); |
| 3043 EXPECT_FALSE(alice.Get(ID).ServerKnows()); |
| 3044 EXPECT_NE(alice.Get(PARENT_ID), fred_id); // This fred was deleted |
| 3045 |
| 3046 // New one was born, this is the old one |
| 3047 Entry dead_fred(&trans, GET_BY_ID, fred_id); |
| 3048 EXPECT_FALSE(dead_fred.good()); |
| 3049 |
| 3050 // Newly born |
| 3051 Entry fred(&trans, GET_BY_ID, alice.Get(PARENT_ID)); |
| 3052 EXPECT_TRUE(fred.Get(IS_UNSYNCED)); |
| 3053 EXPECT_FALSE(fred.Get(IS_UNAPPLIED_UPDATE)); |
| 3054 EXPECT_FALSE(fred.Get(ID).ServerKnows()); |
| 3055 EXPECT_TRUE(fred.Get(PARENT_ID) == susan_id); |
| 3056 |
| 3057 // Unchanged |
| 3058 Entry susan(&trans, GET_BY_ID, susan_id); |
| 3542 ASSERT_TRUE(susan.good()); | 3059 ASSERT_TRUE(susan.good()); |
| 3543 EXPECT_FALSE(susan.Get(IS_UNSYNCED)); | 3060 EXPECT_FALSE(susan.Get(IS_UNSYNCED)); |
| 3544 EXPECT_TRUE(fred.Get(IS_UNSYNCED)); | |
| 3545 EXPECT_TRUE(alice.Get(IS_UNSYNCED)); | |
| 3546 EXPECT_TRUE(bob.Get(IS_UNSYNCED)); | |
| 3547 EXPECT_FALSE(fred.Get(ID).ServerKnows()); | |
| 3548 EXPECT_FALSE(alice.Get(ID).ServerKnows()); | |
| 3549 EXPECT_TRUE(alice.Get(PARENT_ID) == fred.Get(ID)); | |
| 3550 EXPECT_TRUE(bob.Get(PARENT_ID) == alice.Get(ID)); | |
| 3551 EXPECT_TRUE(fred.Get(PARENT_ID) == susan.Get(ID)); | |
| 3552 EXPECT_TRUE(susan.Get(PARENT_ID) == root_id_); | 3061 EXPECT_TRUE(susan.Get(PARENT_ID) == root_id_); |
| 3553 EXPECT_FALSE(fred.Get(IS_UNAPPLIED_UPDATE)); | |
| 3554 EXPECT_FALSE(bob.Get(IS_UNAPPLIED_UPDATE)); | |
| 3555 EXPECT_FALSE(alice.Get(IS_UNAPPLIED_UPDATE)); | |
| 3556 EXPECT_FALSE(susan.Get(IS_UNAPPLIED_UPDATE)); | 3062 EXPECT_FALSE(susan.Get(IS_UNAPPLIED_UPDATE)); |
| 3557 } | 3063 } |
| 3558 syncer_events_.clear(); | 3064 syncer_events_.clear(); |
| 3559 } | 3065 } |
| 3560 | 3066 |
| 3561 // This test is to reproduce a check failure. Sometimes we would get a bad ID | 3067 // This test is to reproduce a check failure. Sometimes we would get a bad ID |
| 3562 // back when creating an entry. | 3068 // back when creating an entry. |
| 3563 TEST_F(SyncerTest, DuplicateIDReturn) { | 3069 TEST_F(SyncerTest, DuplicateIDReturn) { |
| 3564 ScopedDirLookup dir(syncdb_.manager(), syncdb_.name()); | 3070 ScopedDirLookup dir(syncdb_.manager(), syncdb_.name()); |
| 3565 ASSERT_TRUE(dir.good()); | 3071 ASSERT_TRUE(dir.good()); |
| (...skipping 12 matching lines...) Expand all Loading... |
| 3578 } | 3084 } |
| 3579 mock_server_->set_next_new_id(10000); | 3085 mock_server_->set_next_new_id(10000); |
| 3580 EXPECT_TRUE(1 == dir->unsynced_entity_count()); | 3086 EXPECT_TRUE(1 == dir->unsynced_entity_count()); |
| 3581 syncer_->SyncShare(); // we get back a bad id in here (should never happen). | 3087 syncer_->SyncShare(); // we get back a bad id in here (should never happen). |
| 3582 EXPECT_TRUE(1 == dir->unsynced_entity_count()); | 3088 EXPECT_TRUE(1 == dir->unsynced_entity_count()); |
| 3583 syncer_->SyncShare(); // another bad id in here. | 3089 syncer_->SyncShare(); // another bad id in here. |
| 3584 EXPECT_TRUE(0 == dir->unsynced_entity_count()); | 3090 EXPECT_TRUE(0 == dir->unsynced_entity_count()); |
| 3585 syncer_events_.clear(); | 3091 syncer_events_.clear(); |
| 3586 } | 3092 } |
| 3587 | 3093 |
| 3588 // This test is not very useful anymore. It used to trigger a more interesting | |
| 3589 // condition. | |
| 3590 TEST_F(SyncerTest, SimpleConflictOnAnEntry) { | |
| 3591 ScopedDirLookup dir(syncdb_.manager(), syncdb_.name()); | |
| 3592 CHECK(dir.good()); | |
| 3593 { | |
| 3594 WriteTransaction trans(dir, UNITTEST, __FILE__, __LINE__); | |
| 3595 MutableEntry bob(&trans, CREATE, trans.root_id(), PSTR("bob")); | |
| 3596 ASSERT_TRUE(bob.good()); | |
| 3597 bob.Put(IS_UNSYNCED, true); | |
| 3598 WriteTestDataToEntry(&trans, &bob); | |
| 3599 } | |
| 3600 syncer_->SyncShare(); | |
| 3601 syncable::Id bobid; | |
| 3602 { | |
| 3603 WriteTransaction trans(dir, UNITTEST, __FILE__, __LINE__); | |
| 3604 MutableEntry bob(&trans, GET_BY_PATH, PSTR("bob")); | |
| 3605 ASSERT_TRUE(bob.good()); | |
| 3606 EXPECT_FALSE(bob.Get(IS_UNSYNCED)); | |
| 3607 bob.Put(IS_UNSYNCED, true); | |
| 3608 bobid = bob.Get(ID); | |
| 3609 } | |
| 3610 mock_server_->AddUpdateBookmark(1, 0, "jim", 2, 20); | |
| 3611 mock_server_->set_conflict_all_commits(true); | |
| 3612 SyncRepeatedlyToTriggerConflictResolution(state_.get()); | |
| 3613 syncer_events_.clear(); | |
| 3614 } | |
| 3615 | |
| 3616 TEST_F(SyncerTest, DeletedEntryWithBadParentInLoopCalculation) { | 3094 TEST_F(SyncerTest, DeletedEntryWithBadParentInLoopCalculation) { |
| 3617 ScopedDirLookup dir(syncdb_.manager(), syncdb_.name()); | 3095 ScopedDirLookup dir(syncdb_.manager(), syncdb_.name()); |
| 3618 ASSERT_TRUE(dir.good()); | 3096 ASSERT_TRUE(dir.good()); |
| 3619 mock_server_->AddUpdateDirectory(1, 0, "bob", 1, 10); | 3097 mock_server_->AddUpdateDirectory(1, 0, "bob", 1, 10); |
| 3620 syncer_->SyncShare(); | 3098 syncer_->SyncShare(); |
| 3621 { | 3099 { |
| 3622 WriteTransaction trans(dir, UNITTEST, __FILE__, __LINE__); | 3100 WriteTransaction trans(dir, UNITTEST, __FILE__, __LINE__); |
| 3623 MutableEntry bob(&trans, GET_BY_ID, ids_.FromNumber(1)); | 3101 MutableEntry bob(&trans, GET_BY_ID, ids_.FromNumber(1)); |
| 3624 ASSERT_TRUE(bob.good()); | 3102 ASSERT_TRUE(bob.good()); |
| 3625 // This is valid, because the parent could have gone away a long time ago. | 3103 // This is valid, because the parent could have gone away a long time ago. |
| (...skipping 21 matching lines...) Expand all Loading... |
| 3647 local_deleted.Put(BASE_VERSION, 1); | 3125 local_deleted.Put(BASE_VERSION, 1); |
| 3648 local_deleted.Put(IS_DEL, true); | 3126 local_deleted.Put(IS_DEL, true); |
| 3649 local_deleted.Put(IS_UNSYNCED, true); | 3127 local_deleted.Put(IS_UNSYNCED, true); |
| 3650 | 3128 |
| 3651 MutableEntry in_the_way(&trans, CREATE, trans.root_id(), PSTR("name")); | 3129 MutableEntry in_the_way(&trans, CREATE, trans.root_id(), PSTR("name")); |
| 3652 in_the_way.Put(ID, ids_.FromNumber(2)); | 3130 in_the_way.Put(ID, ids_.FromNumber(2)); |
| 3653 in_the_way.Put(BASE_VERSION, 1); | 3131 in_the_way.Put(BASE_VERSION, 1); |
| 3654 | 3132 |
| 3655 MutableEntry update(&trans, CREATE_NEW_UPDATE_ITEM, ids_.FromNumber(3)); | 3133 MutableEntry update(&trans, CREATE_NEW_UPDATE_ITEM, ids_.FromNumber(3)); |
| 3656 update.Put(BASE_VERSION, 1); | 3134 update.Put(BASE_VERSION, 1); |
| 3657 update.Put(SERVER_NAME, PSTR("name")); | 3135 update.Put(SERVER_NON_UNIQUE_NAME, PSTR("name")); |
| 3658 update.Put(PARENT_ID, ids_.FromNumber(0)); | 3136 update.Put(PARENT_ID, ids_.FromNumber(0)); |
| 3659 update.Put(IS_UNAPPLIED_UPDATE, true); | 3137 update.Put(IS_UNAPPLIED_UPDATE, true); |
| 3660 | 3138 |
| 3661 conflict_set.push_back(ids_.FromNumber(1)); | 3139 conflict_set.push_back(ids_.FromNumber(1)); |
| 3662 conflict_set.push_back(ids_.FromNumber(3)); | 3140 conflict_set.push_back(ids_.FromNumber(3)); |
| 3663 } | 3141 } |
| 3664 { | 3142 { |
| 3665 SyncCycleState cycle_state; | 3143 SyncCycleState cycle_state; |
| 3666 SyncerSession session(&cycle_state, state_.get()); | 3144 SyncerSession session(&cycle_state, state_.get()); |
| 3667 WriteTransaction trans(dir, UNITTEST, __FILE__, __LINE__); | 3145 WriteTransaction trans(dir, UNITTEST, __FILE__, __LINE__); |
| (...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3785 MutableEntry entry(&trans, CREATE, trans.root_id(), PSTR("Copy of base")); | 3263 MutableEntry entry(&trans, CREATE, trans.root_id(), PSTR("Copy of base")); |
| 3786 WriteTestDataToEntry(&trans, &entry); | 3264 WriteTestDataToEntry(&trans, &entry); |
| 3787 } | 3265 } |
| 3788 mock_server_->AddUpdateBookmark(1, 0, "Copy of base", 50, 50); | 3266 mock_server_->AddUpdateBookmark(1, 0, "Copy of base", 50, 50); |
| 3789 SyncRepeatedlyToTriggerConflictResolution(state_.get()); | 3267 SyncRepeatedlyToTriggerConflictResolution(state_.get()); |
| 3790 } | 3268 } |
| 3791 | 3269 |
| 3792 // In this test a long changelog contains a child at the start of the changelog | 3270 // In this test a long changelog contains a child at the start of the changelog |
| 3793 // and a parent at the end. While these updates are in progress the client would | 3271 // and a parent at the end. While these updates are in progress the client would |
| 3794 // appear stuck. | 3272 // appear stuck. |
| 3795 TEST_F(SyncerTest, LongChangelistCreatesFakeOrphanedEntries) { | 3273 TEST_F(SyncerTest, LongChangelistWithApplicationConflict) { |
| 3796 ScopedDirLookup dir(syncdb_.manager(), syncdb_.name()); | 3274 ScopedDirLookup dir(syncdb_.manager(), syncdb_.name()); |
| 3797 CHECK(dir.good()); | 3275 CHECK(dir.good()); |
| 3798 const int DEPTH = 400; | 3276 const int DEPTH = 400; |
| 3277 syncable::Id folder_id = ids_.FromNumber(1); |
| 3278 |
| 3799 // First we an item in a folder in the root. However the folder won't come | 3279 // First we an item in a folder in the root. However the folder won't come |
| 3800 // till much later. | 3280 // till much later. |
| 3801 mock_server_->AddUpdateDirectory(99999, 1, "stuck", 1, 1); | 3281 syncable::Id stuck_entry_id = TestIdFactory::FromNumber(99999); |
| 3282 mock_server_->AddUpdateDirectory(stuck_entry_id, |
| 3283 folder_id, "stuck", 1, 1); |
| 3802 mock_server_->SetChangesRemaining(DEPTH - 1); | 3284 mock_server_->SetChangesRemaining(DEPTH - 1); |
| 3803 syncer_->SyncShare(state_.get()); | 3285 syncer_->SyncShare(state_.get()); |
| 3804 | 3286 |
| 3805 // Very long changelist. We should never be stuck. | 3287 // Very long changelist. We should never be stuck. |
| 3806 for (int i = 0; i < DEPTH; i++) { | 3288 for (int i = 0; i < DEPTH; i++) { |
| 3807 mock_server_->SetNewTimestamp(i); | 3289 mock_server_->SetNewTimestamp(i); |
| 3808 mock_server_->SetChangesRemaining(DEPTH - i); | 3290 mock_server_->SetChangesRemaining(DEPTH - i); |
| 3809 syncer_->SyncShare(state_.get()); | 3291 syncer_->SyncShare(state_.get()); |
| 3810 EXPECT_FALSE(SyncerStuck(state_.get())); | 3292 EXPECT_FALSE(SyncerStuck(state_.get())); |
| 3293 |
| 3294 // Ensure our folder hasn't somehow applied. |
| 3295 ReadTransaction trans(dir, __FILE__, __LINE__); |
| 3296 Entry child(&trans, GET_BY_ID, stuck_entry_id); |
| 3297 EXPECT_TRUE(child.good()); |
| 3298 EXPECT_TRUE(child.Get(IS_UNAPPLIED_UPDATE)); |
| 3299 EXPECT_TRUE(child.Get(IS_DEL)); |
| 3300 EXPECT_FALSE(child.Get(IS_UNSYNCED)); |
| 3811 } | 3301 } |
| 3302 |
| 3812 // And finally the folder. | 3303 // And finally the folder. |
| 3813 mock_server_->AddUpdateDirectory(1, 0, "folder", 1, 1); | 3304 mock_server_->AddUpdateDirectory(folder_id, |
| 3305 TestIdFactory::root(), "folder", 1, 1); |
| 3814 mock_server_->SetChangesRemaining(0); | 3306 mock_server_->SetChangesRemaining(0); |
| 3815 LoopSyncShare(syncer_); | 3307 LoopSyncShare(syncer_); |
| 3816 LoopSyncShare(syncer_); | 3308 LoopSyncShare(syncer_); |
| 3817 // Check that everything's as expected after the commit. | 3309 // Check that everything is as expected after the commit. |
| 3818 { | 3310 { |
| 3819 ReadTransaction trans(dir, __FILE__, __LINE__); | 3311 ReadTransaction trans(dir, __FILE__, __LINE__); |
| 3820 Entry entry(&trans, GET_BY_PATH, PSTR("folder")); | 3312 Entry entry(&trans, GET_BY_ID, folder_id); |
| 3821 ASSERT_TRUE(entry.good()); | 3313 ASSERT_TRUE(entry.good()); |
| 3822 Entry child(&trans, GET_BY_PARENTID_AND_NAME, entry.Get(ID), PSTR("stuck")); | 3314 Entry child(&trans, GET_BY_ID, stuck_entry_id); |
| 3315 EXPECT_EQ(entry.Get(ID), child.Get(PARENT_ID)); |
| 3316 EXPECT_EQ(PSTR("stuck"), child.Get(NON_UNIQUE_NAME)); |
| 3823 EXPECT_TRUE(child.good()); | 3317 EXPECT_TRUE(child.good()); |
| 3824 } | 3318 } |
| 3825 } | 3319 } |
| 3826 | 3320 |
| 3827 TEST_F(SyncerTest, DontMergeTwoExistingItems) { | 3321 TEST_F(SyncerTest, DontMergeTwoExistingItems) { |
| 3828 ScopedDirLookup dir(syncdb_.manager(), syncdb_.name()); | 3322 ScopedDirLookup dir(syncdb_.manager(), syncdb_.name()); |
| 3829 EXPECT_TRUE(dir.good()); | 3323 EXPECT_TRUE(dir.good()); |
| 3830 mock_server_->set_conflict_all_commits(true); | 3324 mock_server_->set_conflict_all_commits(true); |
| 3831 mock_server_->AddUpdateBookmark(1, 0, "base", 10, 10); | 3325 mock_server_->AddUpdateBookmark(1, 0, "base", 10, 10); |
| 3832 mock_server_->AddUpdateBookmark(2, 0, "base2", 10, 10); | 3326 mock_server_->AddUpdateBookmark(2, 0, "base2", 10, 10); |
| 3833 syncer_->SyncShare(); | 3327 syncer_->SyncShare(); |
| 3834 { | 3328 { |
| 3835 WriteTransaction trans(dir, UNITTEST, __FILE__, __LINE__); | 3329 WriteTransaction trans(dir, UNITTEST, __FILE__, __LINE__); |
| 3836 MutableEntry entry(&trans, GET_BY_ID, ids_.FromNumber(2)); | 3330 MutableEntry entry(&trans, GET_BY_ID, ids_.FromNumber(2)); |
| 3837 ASSERT_TRUE(entry.good()); | 3331 ASSERT_TRUE(entry.good()); |
| 3838 EXPECT_TRUE(entry.Put(NAME, PSTR("Copy of base"))); | 3332 EXPECT_TRUE(entry.Put(NON_UNIQUE_NAME, PSTR("Copy of base"))); |
| 3839 entry.Put(IS_UNSYNCED, true); | 3333 entry.Put(IS_UNSYNCED, true); |
| 3840 } | 3334 } |
| 3841 mock_server_->AddUpdateBookmark(1, 0, "Copy of base", 50, 50); | 3335 mock_server_->AddUpdateBookmark(1, 0, "Copy of base", 50, 50); |
| 3842 SyncRepeatedlyToTriggerConflictResolution(state_.get()); | 3336 SyncRepeatedlyToTriggerConflictResolution(state_.get()); |
| 3843 { | 3337 { |
| 3844 ReadTransaction trans(dir, __FILE__, __LINE__); | 3338 ReadTransaction trans(dir, __FILE__, __LINE__); |
| 3845 Entry entry1(&trans, GET_BY_ID, ids_.FromNumber(1)); | 3339 Entry entry1(&trans, GET_BY_ID, ids_.FromNumber(1)); |
| 3846 EXPECT_FALSE(entry1.Get(IS_UNAPPLIED_UPDATE)); | 3340 EXPECT_FALSE(entry1.Get(IS_UNAPPLIED_UPDATE)); |
| 3847 EXPECT_FALSE(entry1.Get(IS_UNSYNCED)); | 3341 EXPECT_FALSE(entry1.Get(IS_UNSYNCED)); |
| 3848 EXPECT_FALSE(entry1.Get(IS_DEL)); | 3342 EXPECT_FALSE(entry1.Get(IS_DEL)); |
| 3849 Entry entry2(&trans, GET_BY_ID, ids_.FromNumber(2)); | 3343 Entry entry2(&trans, GET_BY_ID, ids_.FromNumber(2)); |
| 3850 EXPECT_FALSE(entry2.Get(IS_UNAPPLIED_UPDATE)); | 3344 EXPECT_FALSE(entry2.Get(IS_UNAPPLIED_UPDATE)); |
| 3851 EXPECT_TRUE(entry2.Get(IS_UNSYNCED)); | 3345 EXPECT_TRUE(entry2.Get(IS_UNSYNCED)); |
| 3852 EXPECT_FALSE(entry2.Get(IS_DEL)); | 3346 EXPECT_FALSE(entry2.Get(IS_DEL)); |
| 3853 EXPECT_NE(entry1.Get(NAME), entry2.Get(NAME)); | 3347 EXPECT_EQ(entry1.Get(NON_UNIQUE_NAME), entry2.Get(NON_UNIQUE_NAME)); |
| 3854 } | 3348 } |
| 3855 } | 3349 } |
| 3856 | 3350 |
| 3857 TEST_F(SyncerTest, TestUndeleteUpdate) { | 3351 TEST_F(SyncerTest, TestUndeleteUpdate) { |
| 3858 ScopedDirLookup dir(syncdb_.manager(), syncdb_.name()); | 3352 ScopedDirLookup dir(syncdb_.manager(), syncdb_.name()); |
| 3859 EXPECT_TRUE(dir.good()); | 3353 EXPECT_TRUE(dir.good()); |
| 3860 mock_server_->set_conflict_all_commits(true); | 3354 mock_server_->set_conflict_all_commits(true); |
| 3861 mock_server_->AddUpdateDirectory(1, 0, "foo", 1, 1); | 3355 mock_server_->AddUpdateDirectory(1, 0, "foo", 1, 1); |
| 3862 mock_server_->AddUpdateDirectory(2, 1, "bar", 1, 2); | 3356 mock_server_->AddUpdateDirectory(2, 1, "bar", 1, 2); |
| 3863 syncer_->SyncShare(); | 3357 syncer_->SyncShare(); |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3899 ASSERT_TRUE(entry.good()); | 3393 ASSERT_TRUE(entry.good()); |
| 3900 EXPECT_TRUE(entry.Put(PARENT_ID, ids_.FromNumber(1))); | 3394 EXPECT_TRUE(entry.Put(PARENT_ID, ids_.FromNumber(1))); |
| 3901 EXPECT_TRUE(entry.Put(IS_UNSYNCED, true)); | 3395 EXPECT_TRUE(entry.Put(IS_UNSYNCED, true)); |
| 3902 } | 3396 } |
| 3903 syncer_->SyncShare(); | 3397 syncer_->SyncShare(); |
| 3904 // We use the same sync ts as before so our times match up. | 3398 // We use the same sync ts as before so our times match up. |
| 3905 mock_server_->AddUpdateDirectory(2, 1, ":::", 2, 2); | 3399 mock_server_->AddUpdateDirectory(2, 1, ":::", 2, 2); |
| 3906 syncer_->SyncShare(); | 3400 syncer_->SyncShare(); |
| 3907 } | 3401 } |
| 3908 | 3402 |
| 3909 TEST_F(SyncerTest, QuicklyMergeDualCreatedHierarchy) { | |
| 3910 ScopedDirLookup dir(syncdb_.manager(), syncdb_.name()); | |
| 3911 EXPECT_TRUE(dir.good()); | |
| 3912 mock_server_->set_conflict_all_commits(true); | |
| 3913 int depth = 10; | |
| 3914 { | |
| 3915 WriteTransaction trans(dir, UNITTEST, __FILE__, __LINE__); | |
| 3916 syncable::Id parent = root_id_; | |
| 3917 for (int i = 0 ; i < depth ; ++i) { | |
| 3918 MutableEntry entry(&trans, CREATE, parent, PSTR("folder")); | |
| 3919 entry.Put(IS_DIR, true); | |
| 3920 entry.Put(IS_UNSYNCED, true); | |
| 3921 parent = entry.Get(ID); | |
| 3922 } | |
| 3923 } | |
| 3924 for (int i = 0 ; i < depth ; ++i) { | |
| 3925 mock_server_->AddUpdateDirectory(i + 1, i, "folder", 1, 1); | |
| 3926 } | |
| 3927 syncer_->SyncShare(state_.get()); | |
| 3928 syncer_->SyncShare(state_.get()); | |
| 3929 SyncerStatus status(NULL, state_.get()); | |
| 3930 EXPECT_LT(status.consecutive_problem_commits(), 5); | |
| 3931 EXPECT_TRUE(0 == dir->unsynced_entity_count()); | |
| 3932 } | |
| 3933 | |
| 3934 TEST(SortedCollectionsIntersect, SortedCollectionsIntersectTest) { | 3403 TEST(SortedCollectionsIntersect, SortedCollectionsIntersectTest) { |
| 3935 int negative[] = {-3, -2, -1}; | 3404 int negative[] = {-3, -2, -1}; |
| 3936 int straddle[] = {-1, 0, 1}; | 3405 int straddle[] = {-1, 0, 1}; |
| 3937 int positive[] = {1, 2, 3}; | 3406 int positive[] = {1, 2, 3}; |
| 3938 EXPECT_TRUE(SortedCollectionsIntersect(negative, negative + 3, | 3407 EXPECT_TRUE(SortedCollectionsIntersect(negative, negative + 3, |
| 3939 straddle, straddle + 3)); | 3408 straddle, straddle + 3)); |
| 3940 EXPECT_FALSE(SortedCollectionsIntersect(negative, negative + 3, | 3409 EXPECT_FALSE(SortedCollectionsIntersect(negative, negative + 3, |
| 3941 positive, positive + 3)); | 3410 positive, positive + 3)); |
| 3942 EXPECT_TRUE(SortedCollectionsIntersect(straddle, straddle + 3, | 3411 EXPECT_TRUE(SortedCollectionsIntersect(straddle, straddle + 3, |
| 3943 positive, positive + 3)); | 3412 positive, positive + 3)); |
| (...skipping 22 matching lines...) Expand all Loading... |
| 3966 ASSERT_TRUE(bad_parent.good()); | 3435 ASSERT_TRUE(bad_parent.good()); |
| 3967 EXPECT_TRUE(bad_parent.Get(IS_UNAPPLIED_UPDATE)); | 3436 EXPECT_TRUE(bad_parent.Get(IS_UNAPPLIED_UPDATE)); |
| 3968 } | 3437 } |
| 3969 } | 3438 } |
| 3970 | 3439 |
| 3971 const char kRootId[] = "0"; | 3440 const char kRootId[] = "0"; |
| 3972 | 3441 |
| 3973 TEST_F(SyncerTest, DirectoryUpdateTest) { | 3442 TEST_F(SyncerTest, DirectoryUpdateTest) { |
| 3974 ScopedDirLookup dir(syncdb_.manager(), syncdb_.name()); | 3443 ScopedDirLookup dir(syncdb_.manager(), syncdb_.name()); |
| 3975 CHECK(dir.good()); | 3444 CHECK(dir.good()); |
| 3976 mock_server_->AddUpdateDirectory("in_root_id", kRootId, | 3445 |
| 3446 Id in_root_id = ids_.NewServerId(); |
| 3447 Id in_in_root_id = ids_.NewServerId(); |
| 3448 |
| 3449 mock_server_->AddUpdateDirectory(in_root_id, TestIdFactory::root(), |
| 3977 "in_root_name", 2, 2); | 3450 "in_root_name", 2, 2); |
| 3978 mock_server_->AddUpdateDirectory("in_in_root_id", "in_root_id", | 3451 mock_server_->AddUpdateDirectory(in_in_root_id, in_root_id, |
| 3979 "in_in_root_name", 3, 3); | 3452 "in_in_root_name", 3, 3); |
| 3980 syncer_->SyncShare(); | 3453 syncer_->SyncShare(); |
| 3981 { | 3454 { |
| 3982 ReadTransaction trans(dir, __FILE__, __LINE__); | 3455 ReadTransaction trans(dir, __FILE__, __LINE__); |
| 3983 // Entry will have been dropped. | 3456 Entry in_root(&trans, GET_BY_ID, in_root_id); |
| 3984 Entry by_path(&trans, GET_BY_PATH, PSTR("in_root_name")); | 3457 ASSERT_TRUE(in_root.good()); |
| 3985 EXPECT_TRUE(by_path.good()); | 3458 EXPECT_EQ(PSTR("in_root_name"), in_root.Get(NON_UNIQUE_NAME)); |
| 3986 Entry by_path2(&trans, GET_BY_PATH, PSTR("in_root_name") + | 3459 EXPECT_EQ(TestIdFactory::root(), in_root.Get(PARENT_ID)); |
| 3987 PathString(kPathSeparator) + | 3460 |
| 3988 PSTR("in_in_root_name")); | 3461 Entry in_in_root(&trans, GET_BY_ID, in_in_root_id); |
| 3989 EXPECT_TRUE(by_path2.good()); | 3462 ASSERT_TRUE(in_in_root.good()); |
| 3463 EXPECT_EQ(PSTR("in_in_root_name"), in_in_root.Get(NON_UNIQUE_NAME)); |
| 3464 EXPECT_EQ(in_root_id, in_in_root.Get(PARENT_ID)); |
| 3990 } | 3465 } |
| 3991 } | 3466 } |
| 3992 | 3467 |
| 3993 TEST_F(SyncerTest, DirectoryCommitTest) { | 3468 TEST_F(SyncerTest, DirectoryCommitTest) { |
| 3994 syncable::Id in_root, in_dir; | |
| 3995 ScopedDirLookup dir(syncdb_.manager(), syncdb_.name()); | 3469 ScopedDirLookup dir(syncdb_.manager(), syncdb_.name()); |
| 3996 CHECK(dir.good()); | 3470 CHECK(dir.good()); |
| 3471 |
| 3472 syncable::Id in_root_id, in_dir_id; |
| 3473 int64 foo_metahandle; |
| 3474 int64 bar_metahandle; |
| 3475 |
| 3997 { | 3476 { |
| 3998 WriteTransaction wtrans(dir, UNITTEST, __FILE__, __LINE__); | 3477 WriteTransaction wtrans(dir, UNITTEST, __FILE__, __LINE__); |
| 3999 MutableEntry parent(&wtrans, syncable::CREATE, root_id_, PSTR("foo")); | 3478 MutableEntry parent(&wtrans, syncable::CREATE, root_id_, PSTR("foo")); |
| 4000 ASSERT_TRUE(parent.good()); | 3479 ASSERT_TRUE(parent.good()); |
| 4001 parent.Put(syncable::IS_UNSYNCED, true); | 3480 parent.Put(syncable::IS_UNSYNCED, true); |
| 4002 parent.Put(syncable::IS_DIR, true); | 3481 parent.Put(syncable::IS_DIR, true); |
| 4003 in_root = parent.Get(syncable::ID); | 3482 in_root_id = parent.Get(syncable::ID); |
| 3483 foo_metahandle = parent.Get(META_HANDLE); |
| 3484 |
| 4004 MutableEntry child(&wtrans, syncable::CREATE, parent.Get(ID), PSTR("bar")); | 3485 MutableEntry child(&wtrans, syncable::CREATE, parent.Get(ID), PSTR("bar")); |
| 4005 ASSERT_TRUE(child.good()); | 3486 ASSERT_TRUE(child.good()); |
| 4006 child.Put(syncable::IS_UNSYNCED, true); | 3487 child.Put(syncable::IS_UNSYNCED, true); |
| 4007 child.Put(syncable::IS_DIR, true); | 3488 child.Put(syncable::IS_DIR, true); |
| 4008 in_dir = parent.Get(syncable::ID); | 3489 bar_metahandle = child.Get(META_HANDLE); |
| 3490 in_dir_id = parent.Get(syncable::ID); |
| 4009 } | 3491 } |
| 4010 syncer_->SyncShare(); | 3492 syncer_->SyncShare(); |
| 4011 { | 3493 { |
| 4012 ReadTransaction trans(dir, __FILE__, __LINE__); | 3494 ReadTransaction trans(dir, __FILE__, __LINE__); |
| 4013 Entry by_path(&trans, GET_BY_PATH, PSTR("foo")); | 3495 Entry fail_by_old_id_entry(&trans, GET_BY_ID, in_root_id); |
| 4014 ASSERT_TRUE(by_path.good()); | 3496 ASSERT_FALSE(fail_by_old_id_entry.good()); |
| 4015 EXPECT_NE(by_path.Get(syncable::ID), in_root); | 3497 |
| 4016 Entry by_path2(&trans, GET_BY_PATH, PSTR("foo") + | 3498 Entry foo_entry(&trans, GET_BY_HANDLE, foo_metahandle); |
| 4017 PathString(kPathSeparator) + | 3499 ASSERT_TRUE(foo_entry.good()); |
| 4018 PSTR("bar")); | 3500 EXPECT_EQ(PSTR("foo"), foo_entry.Get(NON_UNIQUE_NAME)); |
| 4019 ASSERT_TRUE(by_path2.good()); | 3501 EXPECT_NE(foo_entry.Get(syncable::ID), in_root_id); |
| 4020 EXPECT_NE(by_path2.Get(syncable::ID), in_dir); | 3502 |
| 3503 Entry bar_entry(&trans, GET_BY_HANDLE, bar_metahandle); |
| 3504 ASSERT_TRUE(bar_entry.good()); |
| 3505 EXPECT_EQ(PSTR("bar"), bar_entry.Get(NON_UNIQUE_NAME)); |
| 3506 EXPECT_NE(bar_entry.Get(syncable::ID), in_dir_id); |
| 3507 EXPECT_EQ(foo_entry.Get(syncable::ID), bar_entry.Get(PARENT_ID)); |
| 4021 } | 3508 } |
| 4022 } | 3509 } |
| 4023 | 3510 |
| 4024 namespace { | |
| 4025 | |
| 4026 void CheckEntryVersion(syncable::DirectoryManager* dirmgr, PathString name) { | |
| 4027 ScopedDirLookup dir(dirmgr, name); | |
| 4028 ASSERT_TRUE(dir.good()); | |
| 4029 ReadTransaction trans(dir, __FILE__, __LINE__); | |
| 4030 Entry entry(&trans, GET_BY_PATH, PSTR("foo")); | |
| 4031 ASSERT_TRUE(entry.good()); | |
| 4032 EXPECT_TRUE(entry.Get(BASE_VERSION) == 1); | |
| 4033 } | |
| 4034 | |
| 4035 } // namespace | |
| 4036 | |
| 4037 TEST_F(SyncerTest, ConflictSetSizeReducedToOne) { | 3511 TEST_F(SyncerTest, ConflictSetSizeReducedToOne) { |
| 4038 ScopedDirLookup dir(syncdb_.manager(), syncdb_.name()); | 3512 ScopedDirLookup dir(syncdb_.manager(), syncdb_.name()); |
| 4039 CHECK(dir.good()); | 3513 CHECK(dir.good()); |
| 4040 mock_server_->AddUpdateBookmark(2, 0, "in_root", 1, 1); | 3514 |
| 3515 syncable::Id in_root_id = ids_.NewServerId(); |
| 3516 |
| 3517 mock_server_->AddUpdateBookmark(in_root_id, TestIdFactory::root(), |
| 3518 "in_root", 1, 1); |
| 4041 syncer_->SyncShare(); | 3519 syncer_->SyncShare(); |
| 4042 { | 3520 { |
| 4043 WriteTransaction trans(dir, UNITTEST, __FILE__, __LINE__); | 3521 WriteTransaction trans(dir, UNITTEST, __FILE__, __LINE__); |
| 4044 MutableEntry oentry(&trans, GET_BY_PATH, PSTR("in_root")); | 3522 MutableEntry oentry(&trans, GET_BY_ID, in_root_id); |
| 4045 ASSERT_TRUE(oentry.good()); | 3523 ASSERT_TRUE(oentry.good()); |
| 4046 oentry.Put(NAME, PSTR("old_in_root")); | 3524 oentry.Put(NON_UNIQUE_NAME, PSTR("old_in_root")); |
| 4047 WriteTestDataToEntry(&trans, &oentry); | 3525 WriteTestDataToEntry(&trans, &oentry); |
| 4048 MutableEntry entry(&trans, CREATE, trans.root_id(), PSTR("in_root")); | 3526 MutableEntry entry(&trans, CREATE, trans.root_id(), PSTR("in_root")); |
| 4049 ASSERT_TRUE(entry.good()); | 3527 ASSERT_TRUE(entry.good()); |
| 4050 WriteTestDataToEntry(&trans, &entry); | 3528 WriteTestDataToEntry(&trans, &entry); |
| 4051 } | 3529 } |
| 4052 mock_server_->set_conflict_all_commits(true); | 3530 mock_server_->set_conflict_all_commits(true); |
| 4053 // This SyncShare call used to result in a CHECK failure. | 3531 // This SyncShare call used to result in a CHECK failure. |
| 4054 syncer_->SyncShare(); | 3532 syncer_->SyncShare(); |
| 4055 syncer_events_.clear(); | 3533 syncer_events_.clear(); |
| 4056 } | 3534 } |
| (...skipping 22 matching lines...) Expand all Loading... |
| 4079 | 3557 |
| 4080 EXPECT_TRUE(last_client_command_.has_set_sync_poll_interval()); | 3558 EXPECT_TRUE(last_client_command_.has_set_sync_poll_interval()); |
| 4081 EXPECT_TRUE(last_client_command_.has_set_sync_long_poll_interval()); | 3559 EXPECT_TRUE(last_client_command_.has_set_sync_long_poll_interval()); |
| 4082 EXPECT_TRUE(180 == last_client_command_.set_sync_poll_interval()); | 3560 EXPECT_TRUE(180 == last_client_command_.set_sync_poll_interval()); |
| 4083 EXPECT_TRUE(190 == last_client_command_.set_sync_long_poll_interval()); | 3561 EXPECT_TRUE(190 == last_client_command_.set_sync_long_poll_interval()); |
| 4084 } | 3562 } |
| 4085 | 3563 |
| 4086 TEST_F(SyncerTest, EnsureWeSendUpOldParent) { | 3564 TEST_F(SyncerTest, EnsureWeSendUpOldParent) { |
| 4087 ScopedDirLookup dir(syncdb_.manager(), syncdb_.name()); | 3565 ScopedDirLookup dir(syncdb_.manager(), syncdb_.name()); |
| 4088 CHECK(dir.good()); | 3566 CHECK(dir.good()); |
| 4089 mock_server_->AddUpdateDirectory(1, 0, "folder_one", 1, 1); | 3567 |
| 4090 mock_server_->AddUpdateDirectory(2, 0, "folder_two", 1, 1); | 3568 syncable::Id folder_one_id = ids_.FromNumber(1); |
| 3569 syncable::Id folder_two_id = ids_.FromNumber(2); |
| 3570 |
| 3571 mock_server_->AddUpdateDirectory(folder_one_id, TestIdFactory::root(), |
| 3572 "folder_one", 1, 1); |
| 3573 mock_server_->AddUpdateDirectory(folder_two_id, TestIdFactory::root(), |
| 3574 "folder_two", 1, 1); |
| 4091 syncer_->SyncShare(); | 3575 syncer_->SyncShare(); |
| 4092 { | 3576 { |
| 4093 // A moved entry should send an old parent. | 3577 // A moved entry should send an old parent. |
| 4094 WriteTransaction trans(dir, UNITTEST, __FILE__, __LINE__); | 3578 WriteTransaction trans(dir, UNITTEST, __FILE__, __LINE__); |
| 4095 MutableEntry entry(&trans, GET_BY_PATH, PSTR("folder_one")); | 3579 MutableEntry entry(&trans, GET_BY_ID, folder_one_id); |
| 4096 ASSERT_TRUE(entry.good()); | 3580 ASSERT_TRUE(entry.good()); |
| 4097 entry.Put(PARENT_ID, ids_.FromNumber(2)); | 3581 entry.Put(PARENT_ID, folder_two_id); |
| 4098 entry.Put(IS_UNSYNCED, true); | 3582 entry.Put(IS_UNSYNCED, true); |
| 4099 // A new entry should send no parent. | 3583 // A new entry should send no parent. |
| 4100 MutableEntry create(&trans, CREATE, trans.root_id(), PSTR("new_folder")); | 3584 MutableEntry create(&trans, CREATE, trans.root_id(), PSTR("new_folder")); |
| 4101 create.Put(IS_UNSYNCED, true); | 3585 create.Put(IS_UNSYNCED, true); |
| 4102 } | 3586 } |
| 4103 syncer_->SyncShare(); | 3587 syncer_->SyncShare(); |
| 4104 const sync_pb::CommitMessage& commit = mock_server_->last_sent_commit(); | 3588 const sync_pb::CommitMessage& commit = mock_server_->last_sent_commit(); |
| 4105 ASSERT_TRUE(2 == commit.entries_size()); | 3589 ASSERT_TRUE(2 == commit.entries_size()); |
| 4106 EXPECT_TRUE(commit.entries(0).parent_id_string() == "2"); | 3590 EXPECT_TRUE(commit.entries(0).parent_id_string() == "2"); |
| 4107 EXPECT_TRUE(commit.entries(0).old_parent_id() == "0"); | 3591 EXPECT_TRUE(commit.entries(0).old_parent_id() == "0"); |
| 4108 EXPECT_FALSE(commit.entries(1).has_old_parent_id()); | 3592 EXPECT_FALSE(commit.entries(1).has_old_parent_id()); |
| 4109 } | 3593 } |
| 4110 | 3594 |
| 4111 TEST_F(SyncerTest, Test64BitVersionSupport) { | 3595 TEST_F(SyncerTest, Test64BitVersionSupport) { |
| 4112 ScopedDirLookup dir(syncdb_.manager(), syncdb_.name()); | 3596 ScopedDirLookup dir(syncdb_.manager(), syncdb_.name()); |
| 4113 CHECK(dir.good()); | 3597 CHECK(dir.good()); |
| 4114 int64 really_big_int = std::numeric_limits<int64>::max() - 12; | 3598 int64 really_big_int = std::numeric_limits<int64>::max() - 12; |
| 4115 const PathString name(PSTR("ringo's dang orang ran rings around my o-ring")); | 3599 const PathString name(PSTR("ringo's dang orang ran rings around my o-ring")); |
| 3600 int64 item_metahandle; |
| 4116 | 3601 |
| 4117 // Try writing max int64 to the version fields of a meta entry. | 3602 // Try writing max int64 to the version fields of a meta entry. |
| 4118 { | 3603 { |
| 4119 WriteTransaction wtrans(dir, UNITTEST, __FILE__, __LINE__); | 3604 WriteTransaction wtrans(dir, UNITTEST, __FILE__, __LINE__); |
| 4120 MutableEntry entry(&wtrans, syncable::CREATE, wtrans.root_id(), name); | 3605 MutableEntry entry(&wtrans, syncable::CREATE, wtrans.root_id(), name); |
| 4121 ASSERT_TRUE(entry.good()); | 3606 ASSERT_TRUE(entry.good()); |
| 4122 entry.Put(syncable::BASE_VERSION, really_big_int); | 3607 entry.Put(syncable::BASE_VERSION, really_big_int); |
| 4123 entry.Put(syncable::SERVER_VERSION, really_big_int); | 3608 entry.Put(syncable::SERVER_VERSION, really_big_int); |
| 4124 entry.Put(syncable::ID, syncable::Id::CreateFromServerId("ID")); | 3609 entry.Put(syncable::ID, ids_.NewServerId()); |
| 3610 item_metahandle = entry.Get(META_HANDLE); |
| 4125 } | 3611 } |
| 4126 // Now read it back out and make sure the value is max int64. | 3612 // Now read it back out and make sure the value is max int64. |
| 4127 ReadTransaction rtrans(dir, __FILE__, __LINE__); | 3613 ReadTransaction rtrans(dir, __FILE__, __LINE__); |
| 4128 Entry entry(&rtrans, syncable::GET_BY_PATH, name); | 3614 Entry entry(&rtrans, syncable::GET_BY_HANDLE, item_metahandle); |
| 4129 ASSERT_TRUE(entry.good()); | 3615 ASSERT_TRUE(entry.good()); |
| 4130 EXPECT_TRUE(really_big_int == entry.Get(syncable::BASE_VERSION)); | 3616 EXPECT_TRUE(really_big_int == entry.Get(syncable::BASE_VERSION)); |
| 4131 } | 3617 } |
| 4132 | 3618 |
| 4133 TEST_F(SyncerTest, TestDSStoreDirectorySyncsNormally) { | |
| 4134 syncable::Id item_id = parent_id_; | |
| 4135 mock_server_->AddUpdateDirectory(item_id, | |
| 4136 root_id_, ".DS_Store", 1, 1); | |
| 4137 syncer_->SyncShare(); | |
| 4138 ScopedDirLookup dir(syncdb_.manager(), syncdb_.name()); | |
| 4139 CHECK(dir.good()); | |
| 4140 ReadTransaction trans(dir, __FILE__, __LINE__); | |
| 4141 Entry ds_dir(&trans, GET_BY_PATH, PSTR(".DS_Store")); | |
| 4142 ASSERT_TRUE(ds_dir.good()); | |
| 4143 } | |
| 4144 | |
| 4145 TEST_F(SyncerTest, TestSimpleUndelete) { | 3619 TEST_F(SyncerTest, TestSimpleUndelete) { |
| 4146 Id id = ids_.MakeServer("undeletion item"), root = ids_.root(); | 3620 Id id = ids_.MakeServer("undeletion item"), root = TestIdFactory::root(); |
| 4147 ScopedDirLookup dir(syncdb_.manager(), syncdb_.name()); | 3621 ScopedDirLookup dir(syncdb_.manager(), syncdb_.name()); |
| 4148 EXPECT_TRUE(dir.good()); | 3622 EXPECT_TRUE(dir.good()); |
| 4149 mock_server_->set_conflict_all_commits(true); | 3623 mock_server_->set_conflict_all_commits(true); |
| 4150 // Let there be an entry from the server. | 3624 // Let there be an entry from the server. |
| 4151 mock_server_->AddUpdateBookmark(id, root, "foo", 1, 10); | 3625 mock_server_->AddUpdateBookmark(id, root, "foo", 1, 10); |
| 4152 syncer_->SyncShare(); | 3626 syncer_->SyncShare(); |
| 4153 // Check it out and delete it. | 3627 // Check it out and delete it. |
| 4154 { | 3628 { |
| 4155 WriteTransaction wtrans(dir, UNITTEST, __FILE__, __LINE__); | 3629 WriteTransaction wtrans(dir, UNITTEST, __FILE__, __LINE__); |
| 4156 MutableEntry entry(&wtrans, GET_BY_ID, id); | 3630 MutableEntry entry(&wtrans, GET_BY_ID, id); |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4196 Entry entry(&trans, GET_BY_ID, id); | 3670 Entry entry(&trans, GET_BY_ID, id); |
| 4197 ASSERT_TRUE(entry.good()); | 3671 ASSERT_TRUE(entry.good()); |
| 4198 EXPECT_FALSE(entry.Get(IS_UNAPPLIED_UPDATE)); | 3672 EXPECT_FALSE(entry.Get(IS_UNAPPLIED_UPDATE)); |
| 4199 EXPECT_FALSE(entry.Get(IS_UNSYNCED)); | 3673 EXPECT_FALSE(entry.Get(IS_UNSYNCED)); |
| 4200 EXPECT_FALSE(entry.Get(IS_DEL)); | 3674 EXPECT_FALSE(entry.Get(IS_DEL)); |
| 4201 EXPECT_FALSE(entry.Get(SERVER_IS_DEL)); | 3675 EXPECT_FALSE(entry.Get(SERVER_IS_DEL)); |
| 4202 } | 3676 } |
| 4203 } | 3677 } |
| 4204 | 3678 |
| 4205 TEST_F(SyncerTest, TestUndeleteWithMissingDeleteUpdate) { | 3679 TEST_F(SyncerTest, TestUndeleteWithMissingDeleteUpdate) { |
| 4206 Id id = ids_.MakeServer("undeletion item"), root = ids_.root(); | 3680 Id id = ids_.MakeServer("undeletion item"), root = TestIdFactory::root(); |
| 4207 ScopedDirLookup dir(syncdb_.manager(), syncdb_.name()); | 3681 ScopedDirLookup dir(syncdb_.manager(), syncdb_.name()); |
| 4208 EXPECT_TRUE(dir.good()); | 3682 EXPECT_TRUE(dir.good()); |
| 4209 // Let there be a entry, from the server. | 3683 // Let there be a entry, from the server. |
| 4210 mock_server_->set_conflict_all_commits(true); | 3684 mock_server_->set_conflict_all_commits(true); |
| 4211 mock_server_->AddUpdateBookmark(id, root, "foo", 1, 10); | 3685 mock_server_->AddUpdateBookmark(id, root, "foo", 1, 10); |
| 4212 syncer_->SyncShare(); | 3686 syncer_->SyncShare(); |
| 4213 // Check it out and delete it. | 3687 // Check it out and delete it. |
| 4214 { | 3688 { |
| 4215 WriteTransaction wtrans(dir, UNITTEST, __FILE__, __LINE__); | 3689 WriteTransaction wtrans(dir, UNITTEST, __FILE__, __LINE__); |
| 4216 MutableEntry entry(&wtrans, GET_BY_ID, id); | 3690 MutableEntry entry(&wtrans, GET_BY_ID, id); |
| (...skipping 27 matching lines...) Expand all Loading... |
| 4244 ASSERT_TRUE(entry.good()); | 3718 ASSERT_TRUE(entry.good()); |
| 4245 EXPECT_FALSE(entry.Get(IS_UNAPPLIED_UPDATE)); | 3719 EXPECT_FALSE(entry.Get(IS_UNAPPLIED_UPDATE)); |
| 4246 EXPECT_FALSE(entry.Get(IS_UNSYNCED)); | 3720 EXPECT_FALSE(entry.Get(IS_UNSYNCED)); |
| 4247 EXPECT_FALSE(entry.Get(IS_DEL)); | 3721 EXPECT_FALSE(entry.Get(IS_DEL)); |
| 4248 EXPECT_FALSE(entry.Get(SERVER_IS_DEL)); | 3722 EXPECT_FALSE(entry.Get(SERVER_IS_DEL)); |
| 4249 } | 3723 } |
| 4250 } | 3724 } |
| 4251 | 3725 |
| 4252 TEST_F(SyncerTest, TestUndeleteIgnoreCorrectlyUnappliedUpdate) { | 3726 TEST_F(SyncerTest, TestUndeleteIgnoreCorrectlyUnappliedUpdate) { |
| 4253 Id id1 = ids_.MakeServer("first"), id2 = ids_.MakeServer("second"); | 3727 Id id1 = ids_.MakeServer("first"), id2 = ids_.MakeServer("second"); |
| 4254 Id root = ids_.root(); | 3728 Id root = TestIdFactory::root(); |
| 4255 ScopedDirLookup dir(syncdb_.manager(), syncdb_.name()); | 3729 ScopedDirLookup dir(syncdb_.manager(), syncdb_.name()); |
| 4256 EXPECT_TRUE(dir.good()); | 3730 EXPECT_TRUE(dir.good()); |
| 4257 // Duplicate! expect path clashing! | 3731 // Duplicate! expect path clashing! |
| 4258 mock_server_->set_conflict_all_commits(true); | 3732 mock_server_->set_conflict_all_commits(true); |
| 4259 mock_server_->AddUpdateBookmark(id1, root, "foo", 1, 10); | 3733 mock_server_->AddUpdateBookmark(id1, root, "foo", 1, 10); |
| 4260 mock_server_->AddUpdateBookmark(id2, root, "foo", 1, 10); | 3734 mock_server_->AddUpdateBookmark(id2, root, "foo", 1, 10); |
| 4261 syncer_->SyncShare(); | 3735 syncer_->SyncShare(); |
| 4262 mock_server_->AddUpdateBookmark(id2, root, "foo2", 1, 10); | 3736 mock_server_->AddUpdateBookmark(id2, root, "foo2", 1, 10); |
| 4263 syncer_->SyncShare(); // Now just don't explode. | 3737 syncer_->SyncShare(); // Now just don't explode. |
| 4264 } | 3738 } |
| (...skipping 24 matching lines...) Expand all Loading... |
| 4289 EXPECT_TRUE(dir.good()); | 3763 EXPECT_TRUE(dir.good()); |
| 4290 // As a hurdle, introduce an item whose name is the same as the tag value | 3764 // As a hurdle, introduce an item whose name is the same as the tag value |
| 4291 // we'll use later. | 3765 // we'll use later. |
| 4292 int64 hurdle_handle = CreateUnsyncedDirectory(PSTR("bob"), "id_bob"); | 3766 int64 hurdle_handle = CreateUnsyncedDirectory(PSTR("bob"), "id_bob"); |
| 4293 { | 3767 { |
| 4294 ReadTransaction trans(dir, __FILE__, __LINE__); | 3768 ReadTransaction trans(dir, __FILE__, __LINE__); |
| 4295 Entry hurdle(&trans, GET_BY_HANDLE, hurdle_handle); | 3769 Entry hurdle(&trans, GET_BY_HANDLE, hurdle_handle); |
| 4296 ASSERT_TRUE(hurdle.good()); | 3770 ASSERT_TRUE(hurdle.good()); |
| 4297 ASSERT_TRUE(!hurdle.Get(IS_DEL)); | 3771 ASSERT_TRUE(!hurdle.Get(IS_DEL)); |
| 4298 ASSERT_TRUE(hurdle.Get(SINGLETON_TAG).empty()); | 3772 ASSERT_TRUE(hurdle.Get(SINGLETON_TAG).empty()); |
| 4299 ASSERT_TRUE(hurdle.GetName().value() == PSTR("bob")); | 3773 ASSERT_TRUE(hurdle.Get(NON_UNIQUE_NAME) == PSTR("bob")); |
| 4300 | 3774 |
| 4301 // Try to lookup by the tagname. These should fail. | 3775 // Try to lookup by the tagname. These should fail. |
| 4302 Entry tag_alpha(&trans, GET_BY_TAG, PSTR("alpha")); | 3776 Entry tag_alpha(&trans, GET_BY_TAG, PSTR("alpha")); |
| 4303 EXPECT_FALSE(tag_alpha.good()); | 3777 EXPECT_FALSE(tag_alpha.good()); |
| 4304 Entry tag_bob(&trans, GET_BY_TAG, PSTR("bob")); | 3778 Entry tag_bob(&trans, GET_BY_TAG, PSTR("bob")); |
| 4305 EXPECT_FALSE(tag_bob.good()); | 3779 EXPECT_FALSE(tag_bob.good()); |
| 4306 } | 3780 } |
| 4307 | 3781 |
| 4308 // Now download some tagged items as updates. | 3782 // Now download some tagged items as updates. |
| 4309 mock_server_->AddUpdateDirectory(1, 0, "update1", 1, 10); | 3783 mock_server_->AddUpdateDirectory(1, 0, "update1", 1, 10); |
| 4310 mock_server_->SetLastUpdateSingletonTag("alpha"); | 3784 mock_server_->SetLastUpdateSingletonTag("alpha"); |
| 4311 mock_server_->AddUpdateDirectory(2, 0, "update2", 2, 20); | 3785 mock_server_->AddUpdateDirectory(2, 0, "update2", 2, 20); |
| 4312 mock_server_->SetLastUpdateSingletonTag("bob"); | 3786 mock_server_->SetLastUpdateSingletonTag("bob"); |
| 4313 syncer_->SyncShare(); | 3787 syncer_->SyncShare(); |
| 4314 | 3788 |
| 4315 { | 3789 { |
| 4316 ReadTransaction trans(dir, __FILE__, __LINE__); | 3790 ReadTransaction trans(dir, __FILE__, __LINE__); |
| 4317 | 3791 |
| 4318 // The new items should be applied as new entries, and we should be able | 3792 // The new items should be applied as new entries, and we should be able |
| 4319 // to look them up by their tag values. | 3793 // to look them up by their tag values. |
| 4320 Entry tag_alpha(&trans, GET_BY_TAG, PSTR("alpha")); | 3794 Entry tag_alpha(&trans, GET_BY_TAG, PSTR("alpha")); |
| 4321 ASSERT_TRUE(tag_alpha.good()); | 3795 ASSERT_TRUE(tag_alpha.good()); |
| 4322 ASSERT_TRUE(!tag_alpha.Get(IS_DEL)); | 3796 ASSERT_TRUE(!tag_alpha.Get(IS_DEL)); |
| 4323 ASSERT_TRUE(tag_alpha.Get(SINGLETON_TAG) == PSTR("alpha")); | 3797 ASSERT_TRUE(tag_alpha.Get(SINGLETON_TAG) == PSTR("alpha")); |
| 4324 ASSERT_TRUE(tag_alpha.GetName().value() == PSTR("update1")); | 3798 ASSERT_TRUE(tag_alpha.Get(NON_UNIQUE_NAME) == PSTR("update1")); |
| 4325 Entry tag_bob(&trans, GET_BY_TAG, PSTR("bob")); | 3799 Entry tag_bob(&trans, GET_BY_TAG, PSTR("bob")); |
| 4326 ASSERT_TRUE(tag_bob.good()); | 3800 ASSERT_TRUE(tag_bob.good()); |
| 4327 ASSERT_TRUE(!tag_bob.Get(IS_DEL)); | 3801 ASSERT_TRUE(!tag_bob.Get(IS_DEL)); |
| 4328 ASSERT_TRUE(tag_bob.Get(SINGLETON_TAG) == PSTR("bob")); | 3802 ASSERT_TRUE(tag_bob.Get(SINGLETON_TAG) == PSTR("bob")); |
| 4329 ASSERT_TRUE(tag_bob.GetName().value() == PSTR("update2")); | 3803 ASSERT_TRUE(tag_bob.Get(NON_UNIQUE_NAME) == PSTR("update2")); |
| 4330 // The old item should be unchanged. | 3804 // The old item should be unchanged. |
| 4331 Entry hurdle(&trans, GET_BY_HANDLE, hurdle_handle); | 3805 Entry hurdle(&trans, GET_BY_HANDLE, hurdle_handle); |
| 4332 ASSERT_TRUE(hurdle.good()); | 3806 ASSERT_TRUE(hurdle.good()); |
| 4333 ASSERT_TRUE(!hurdle.Get(IS_DEL)); | 3807 ASSERT_TRUE(!hurdle.Get(IS_DEL)); |
| 4334 ASSERT_TRUE(hurdle.Get(SINGLETON_TAG).empty()); | 3808 ASSERT_TRUE(hurdle.Get(SINGLETON_TAG).empty()); |
| 4335 ASSERT_TRUE(hurdle.GetName().value() == PSTR("bob")); | 3809 ASSERT_TRUE(hurdle.Get(NON_UNIQUE_NAME) == PSTR("bob")); |
| 4336 } | 3810 } |
| 4337 } | 3811 } |
| 4338 | 3812 |
| 4339 class SyncerPositionUpdateTest : public SyncerTest { | 3813 class SyncerPositionUpdateTest : public SyncerTest { |
| 4340 public: | 3814 public: |
| 4341 SyncerPositionUpdateTest() : next_update_id_(1), next_revision_(1) {} | 3815 SyncerPositionUpdateTest() : next_update_id_(1), next_revision_(1) {} |
| 4342 | 3816 |
| 4343 protected: | 3817 protected: |
| 4344 void ExpectLocalItemsInServerOrder() { | 3818 void ExpectLocalItemsInServerOrder() { |
| 4345 if (position_map_.empty()) | 3819 if (position_map_.empty()) |
| (...skipping 203 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4549 Add(low_id_); | 4023 Add(low_id_); |
| 4550 Add(high_id_); | 4024 Add(high_id_); |
| 4551 syncer_->SyncShare(); | 4025 syncer_->SyncShare(); |
| 4552 ExpectLocalOrderIsByServerId(); | 4026 ExpectLocalOrderIsByServerId(); |
| 4553 } | 4027 } |
| 4554 | 4028 |
| 4555 const SyncerTest::CommitOrderingTest | 4029 const SyncerTest::CommitOrderingTest |
| 4556 SyncerTest::CommitOrderingTest::LAST_COMMIT_ITEM = {-1, TestIdFactory::root()}; | 4030 SyncerTest::CommitOrderingTest::LAST_COMMIT_ITEM = {-1, TestIdFactory::root()}; |
| 4557 | 4031 |
| 4558 } // namespace browser_sync | 4032 } // namespace browser_sync |
| OLD | NEW |