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 |