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

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

Issue 371029: Remove unique naming. (Closed)
Patch Set: Ready and about to go in! Created 11 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « chrome/browser/sync/engine/syncer_types.h ('k') | chrome/browser/sync/engine/syncer_util.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2009 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE 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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
OLDNEW
« no previous file with comments | « chrome/browser/sync/engine/syncer_types.h ('k') | chrome/browser/sync/engine/syncer_util.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698