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

Side by Side Diff: sync/engine/apply_updates_and_resolve_conflicts_command_unittest.cc

Issue 11636006: WIP: The Bookmark Position Megapatch (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Various updates, including switch suffix to unique_client_tag style Created 8 years 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 | Annotate | Revision Log
« no previous file with comments | « sync/engine/apply_control_data_updates_unittest.cc ('k') | sync/engine/build_commit_command.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) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include <string> 5 #include <string>
6 6
7 #include "base/location.h" 7 #include "base/location.h"
8 #include "base/memory/scoped_ptr.h" 8 #include "base/memory/scoped_ptr.h"
9 #include "base/stringprintf.h" 9 #include "base/stringprintf.h"
10 #include "sync/engine/apply_updates_and_resolve_conflicts_command.h" 10 #include "sync/engine/apply_updates_and_resolve_conflicts_command.h"
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
64 64
65 protected: 65 protected:
66 DISALLOW_COPY_AND_ASSIGN(ApplyUpdatesAndResolveConflictsCommandTest); 66 DISALLOW_COPY_AND_ASSIGN(ApplyUpdatesAndResolveConflictsCommandTest);
67 67
68 ApplyUpdatesAndResolveConflictsCommand apply_updates_command_; 68 ApplyUpdatesAndResolveConflictsCommand apply_updates_command_;
69 scoped_ptr<TestEntryFactory> entry_factory_; 69 scoped_ptr<TestEntryFactory> entry_factory_;
70 }; 70 };
71 71
72 TEST_F(ApplyUpdatesAndResolveConflictsCommandTest, Simple) { 72 TEST_F(ApplyUpdatesAndResolveConflictsCommandTest, Simple) {
73 string root_server_id = syncable::GetNullId().GetServerId(); 73 string root_server_id = syncable::GetNullId().GetServerId();
74 entry_factory_->CreateUnappliedNewItemWithParent("parent", 74 entry_factory_->CreateUnappliedNewBookmarkItemWithParent(
75 DefaultBookmarkSpecifics(), 75 "parent", DefaultBookmarkSpecifics(), root_server_id);
76 root_server_id); 76 entry_factory_->CreateUnappliedNewBookmarkItemWithParent(
77 entry_factory_->CreateUnappliedNewItemWithParent("child", 77 "child", DefaultBookmarkSpecifics(), "parent");
78 DefaultBookmarkSpecifics(),
79 "parent");
80 78
81 ExpectGroupToChange(apply_updates_command_, GROUP_UI); 79 ExpectGroupToChange(apply_updates_command_, GROUP_UI);
82 apply_updates_command_.ExecuteImpl(session()); 80 apply_updates_command_.ExecuteImpl(session());
83 81
84 const sessions::StatusController& status = session()->status_controller(); 82 const sessions::StatusController& status = session()->status_controller();
85 EXPECT_EQ(0, status.num_encryption_conflicts()) 83 EXPECT_EQ(0, status.num_encryption_conflicts())
86 << "Simple update shouldn't result in conflicts"; 84 << "Simple update shouldn't result in conflicts";
87 EXPECT_EQ(0, status.num_hierarchy_conflicts()) 85 EXPECT_EQ(0, status.num_hierarchy_conflicts())
88 << "Simple update shouldn't result in conflicts"; 86 << "Simple update shouldn't result in conflicts";
89 EXPECT_EQ(2, status.num_updates_applied()) 87 EXPECT_EQ(2, status.num_updates_applied())
90 << "All items should have been successfully applied"; 88 << "All items should have been successfully applied";
91 } 89 }
92 90
93 TEST_F(ApplyUpdatesAndResolveConflictsCommandTest, 91 TEST_F(ApplyUpdatesAndResolveConflictsCommandTest,
94 UpdateWithChildrenBeforeParents) { 92 UpdateWithChildrenBeforeParents) {
95 // Set a bunch of updates which are difficult to apply in the order 93 // Set a bunch of updates which are difficult to apply in the order
96 // they're received due to dependencies on other unseen items. 94 // they're received due to dependencies on other unseen items.
97 string root_server_id = syncable::GetNullId().GetServerId(); 95 string root_server_id = syncable::GetNullId().GetServerId();
98 entry_factory_->CreateUnappliedNewItemWithParent( 96 entry_factory_->CreateUnappliedNewBookmarkItemWithParent(
99 "a_child_created_first", DefaultBookmarkSpecifics(), "parent"); 97 "a_child_created_first", DefaultBookmarkSpecifics(), "parent");
100 entry_factory_->CreateUnappliedNewItemWithParent( 98 entry_factory_->CreateUnappliedNewBookmarkItemWithParent(
101 "x_child_created_first", DefaultBookmarkSpecifics(), "parent"); 99 "x_child_created_first", DefaultBookmarkSpecifics(), "parent");
102 entry_factory_->CreateUnappliedNewItemWithParent( 100 entry_factory_->CreateUnappliedNewBookmarkItemWithParent(
103 "parent", DefaultBookmarkSpecifics(), root_server_id); 101 "parent", DefaultBookmarkSpecifics(), root_server_id);
104 entry_factory_->CreateUnappliedNewItemWithParent( 102 entry_factory_->CreateUnappliedNewBookmarkItemWithParent(
105 "a_child_created_second", DefaultBookmarkSpecifics(), "parent"); 103 "a_child_created_second", DefaultBookmarkSpecifics(), "parent");
106 entry_factory_->CreateUnappliedNewItemWithParent( 104 entry_factory_->CreateUnappliedNewBookmarkItemWithParent(
107 "x_child_created_second", DefaultBookmarkSpecifics(), "parent"); 105 "x_child_created_second", DefaultBookmarkSpecifics(), "parent");
108 106
109 ExpectGroupToChange(apply_updates_command_, GROUP_UI); 107 ExpectGroupToChange(apply_updates_command_, GROUP_UI);
110 apply_updates_command_.ExecuteImpl(session()); 108 apply_updates_command_.ExecuteImpl(session());
111 109
112 const sessions::StatusController& status = session()->status_controller(); 110 const sessions::StatusController& status = session()->status_controller();
113 EXPECT_EQ(5, status.num_updates_applied()) 111 EXPECT_EQ(5, status.num_updates_applied())
114 << "All updates should have been successfully applied"; 112 << "All updates should have been successfully applied";
115 } 113 }
116 114
117 // Runs the ApplyUpdatesAndResolveConflictsCommand on an item that has both 115 // Runs the ApplyUpdatesAndResolveConflictsCommand on an item that has both
118 // local and remote modifications (IS_UNSYNCED and IS_UNAPPLIED_UPDATE). We 116 // local and remote modifications (IS_UNSYNCED and IS_UNAPPLIED_UPDATE). We
119 // expect the command to detect that this update can't be applied because it is 117 // expect the command to detect that this update can't be applied because it is
120 // in a CONFLICT state. 118 // in a CONFLICT state.
121 TEST_F(ApplyUpdatesAndResolveConflictsCommandTest, SimpleConflict) { 119 TEST_F(ApplyUpdatesAndResolveConflictsCommandTest, SimpleConflict) {
122 entry_factory_->CreateUnappliedAndUnsyncedItem("item", BOOKMARKS); 120 entry_factory_->CreateUnappliedAndUnsyncedBookmarkItem("item");
123 121
124 ExpectGroupToChange(apply_updates_command_, GROUP_UI); 122 ExpectGroupToChange(apply_updates_command_, GROUP_UI);
125 apply_updates_command_.ExecuteImpl(session()); 123 apply_updates_command_.ExecuteImpl(session());
126 124
127 const sessions::StatusController& status = session()->status_controller(); 125 const sessions::StatusController& status = session()->status_controller();
128 EXPECT_EQ(1, status.num_server_overwrites()) 126 EXPECT_EQ(1, status.num_server_overwrites())
129 << "Unsynced and unapplied item conflict should be resolved"; 127 << "Unsynced and unapplied item conflict should be resolved";
130 EXPECT_EQ(0, status.num_updates_applied()) 128 EXPECT_EQ(0, status.num_updates_applied())
131 << "Update should not be applied; we should override the server."; 129 << "Update should not be applied; we should override the server.";
132 } 130 }
133 131
134 // Runs the ApplyUpdatesAndResolveConflictsCommand on an item that has both 132 // Runs the ApplyUpdatesAndResolveConflictsCommand on an item that has both
135 // local and remote modifications *and* the remote modification cannot be 133 // local and remote modifications *and* the remote modification cannot be
136 // applied without violating the tree constraints. We expect the command to 134 // applied without violating the tree constraints. We expect the command to
137 // detect that this update can't be applied and that this situation can't be 135 // detect that this update can't be applied and that this situation can't be
138 // resolved with the simple conflict processing logic; it is in a 136 // resolved with the simple conflict processing logic; it is in a
139 // CONFLICT_HIERARCHY state. 137 // CONFLICT_HIERARCHY state.
140 TEST_F(ApplyUpdatesAndResolveConflictsCommandTest, HierarchyAndSimpleConflict) { 138 TEST_F(ApplyUpdatesAndResolveConflictsCommandTest, HierarchyAndSimpleConflict) {
141 // Create a simply-conflicting item. It will start with valid parent ids. 139 // Create a simply-conflicting item. It will start with valid parent ids.
142 int64 handle = entry_factory_->CreateUnappliedAndUnsyncedItem( 140 int64 handle = entry_factory_->CreateUnappliedAndUnsyncedBookmarkItem(
143 "orphaned_by_server", BOOKMARKS); 141 "orphaned_by_server");
144 { 142 {
145 // Manually set the SERVER_PARENT_ID to bad value. 143 // Manually set the SERVER_PARENT_ID to bad value.
146 // A bad parent indicates a hierarchy conflict. 144 // A bad parent indicates a hierarchy conflict.
147 WriteTransaction trans(FROM_HERE, UNITTEST, directory()); 145 WriteTransaction trans(FROM_HERE, UNITTEST, directory());
148 MutableEntry entry(&trans, syncable::GET_BY_HANDLE, handle); 146 MutableEntry entry(&trans, syncable::GET_BY_HANDLE, handle);
149 ASSERT_TRUE(entry.good()); 147 ASSERT_TRUE(entry.good());
150 148
151 entry.Put(syncable::SERVER_PARENT_ID, 149 entry.Put(syncable::SERVER_PARENT_ID,
152 TestIdFactory::MakeServer("bogus_parent")); 150 TestIdFactory::MakeServer("bogus_parent"));
153 } 151 }
154 152
155 ExpectGroupToChange(apply_updates_command_, GROUP_UI); 153 ExpectGroupToChange(apply_updates_command_, GROUP_UI);
156 apply_updates_command_.ExecuteImpl(session()); 154 apply_updates_command_.ExecuteImpl(session());
157 155
158 const sessions::StatusController& status = session()->status_controller(); 156 const sessions::StatusController& status = session()->status_controller();
159 EXPECT_EQ(1, status.num_hierarchy_conflicts()); 157 EXPECT_EQ(1, status.num_hierarchy_conflicts());
160 } 158 }
161 159
162 160
163 // Runs the ApplyUpdatesAndResolveConflictsCommand on an item with remote 161 // Runs the ApplyUpdatesAndResolveConflictsCommand on an item with remote
164 // modifications that would create a directory loop if the update were applied. 162 // modifications that would create a directory loop if the update were applied.
165 // We expect the command to detect that this update can't be applied because it 163 // We expect the command to detect that this update can't be applied because it
166 // is in a CONFLICT_HIERARCHY state. 164 // is in a CONFLICT_HIERARCHY state.
167 TEST_F(ApplyUpdatesAndResolveConflictsCommandTest, 165 TEST_F(ApplyUpdatesAndResolveConflictsCommandTest,
168 HierarchyConflictDirectoryLoop) { 166 HierarchyConflictDirectoryLoop) {
169 // Item 'X' locally has parent of 'root'. Server is updating it to have 167 // Item 'X' locally has parent of 'root'. Server is updating it to have
170 // parent of 'Y'. 168 // parent of 'Y'.
171 { 169 {
172 // Create it as a child of root node. 170 // Create it as a child of root node.
173 int64 handle = entry_factory_->CreateSyncedItem("X", BOOKMARKS, true); 171 int64 handle = entry_factory_->CreateSyncedBookmarkItem("X", true);
174 172
175 WriteTransaction trans(FROM_HERE, UNITTEST, directory()); 173 WriteTransaction trans(FROM_HERE, UNITTEST, directory());
176 MutableEntry entry(&trans, syncable::GET_BY_HANDLE, handle); 174 MutableEntry entry(&trans, syncable::GET_BY_HANDLE, handle);
177 ASSERT_TRUE(entry.good()); 175 ASSERT_TRUE(entry.good());
178 176
179 // Re-parent from root to "Y" 177 // Re-parent from root to "Y"
180 entry.Put(syncable::SERVER_VERSION, entry_factory_->GetNextRevision()); 178 entry.Put(syncable::SERVER_VERSION, entry_factory_->GetNextRevision());
181 entry.Put(syncable::IS_UNAPPLIED_UPDATE, true); 179 entry.Put(syncable::IS_UNAPPLIED_UPDATE, true);
182 entry.Put(syncable::SERVER_PARENT_ID, TestIdFactory::MakeServer("Y")); 180 entry.Put(syncable::SERVER_PARENT_ID, TestIdFactory::MakeServer("Y"));
183 } 181 }
184 182
185 // Item 'Y' is child of 'X'. 183 // Item 'Y' is child of 'X'.
186 entry_factory_->CreateUnsyncedItem( 184 entry_factory_->CreateUnsyncedBookmarkItem(
187 TestIdFactory::MakeServer("Y"), TestIdFactory::MakeServer("X"), "Y", true, 185 TestIdFactory::MakeServer("Y"), TestIdFactory::MakeServer("X"), "Y", true,
188 BOOKMARKS, NULL); 186 NULL);
189 187
190 // If the server's update were applied, we would have X be a child of Y, and Y 188 // If the server's update were applied, we would have X be a child of Y, and Y
191 // as a child of X. That's a directory loop. The UpdateApplicator should 189 // as a child of X. That's a directory loop. The UpdateApplicator should
192 // prevent the update from being applied and note that this is a hierarchy 190 // prevent the update from being applied and note that this is a hierarchy
193 // conflict. 191 // conflict.
194 192
195 ExpectGroupToChange(apply_updates_command_, GROUP_UI); 193 ExpectGroupToChange(apply_updates_command_, GROUP_UI);
196 apply_updates_command_.ExecuteImpl(session()); 194 apply_updates_command_.ExecuteImpl(session());
197 195
198 const sessions::StatusController& status = session()->status_controller(); 196 const sessions::StatusController& status = session()->status_controller();
199 197
200 // This should count as a hierarchy conflict. 198 // This should count as a hierarchy conflict.
201 EXPECT_EQ(1, status.num_hierarchy_conflicts()); 199 EXPECT_EQ(1, status.num_hierarchy_conflicts());
202 } 200 }
203 201
204 // Runs the ApplyUpdatesAndResolveConflictsCommand on a directory where the 202 // Runs the ApplyUpdatesAndResolveConflictsCommand on a directory where the
205 // server sent us an update to add a child to a locally deleted (and unsynced) 203 // server sent us an update to add a child to a locally deleted (and unsynced)
206 // parent. We expect the command to not apply the update and to indicate the 204 // parent. We expect the command to not apply the update and to indicate the
207 // update is in a CONFLICT_HIERARCHY state. 205 // update is in a CONFLICT_HIERARCHY state.
208 TEST_F(ApplyUpdatesAndResolveConflictsCommandTest, 206 TEST_F(ApplyUpdatesAndResolveConflictsCommandTest,
209 HierarchyConflictDeletedParent) { 207 HierarchyConflictDeletedParent) {
210 // Create a locally deleted parent item. 208 // Create a locally deleted parent item.
211 int64 parent_handle; 209 int64 parent_handle;
212 entry_factory_->CreateUnsyncedItem( 210 entry_factory_->CreateUnsyncedBookmarkItem(
213 Id::CreateFromServerId("parent"), TestIdFactory::root(), 211 Id::CreateFromServerId("parent"), TestIdFactory::root(),
214 "parent", true, BOOKMARKS, &parent_handle); 212 "parent", true, &parent_handle);
215 { 213 {
216 WriteTransaction trans(FROM_HERE, UNITTEST, directory()); 214 WriteTransaction trans(FROM_HERE, UNITTEST, directory());
217 MutableEntry entry(&trans, syncable::GET_BY_HANDLE, parent_handle); 215 MutableEntry entry(&trans, syncable::GET_BY_HANDLE, parent_handle);
218 entry.Put(syncable::IS_DEL, true); 216 entry.Put(syncable::IS_DEL, true);
219 } 217 }
220 218
221 // Create an incoming child from the server. 219 // Create an incoming child from the server.
222 entry_factory_->CreateUnappliedNewItemWithParent( 220 entry_factory_->CreateUnappliedNewItemWithParent(
223 "child", DefaultBookmarkSpecifics(), "parent"); 221 "child", DefaultBookmarkSpecifics(), "parent");
224 222
(...skipping 10 matching lines...) Expand all
235 233
236 // Runs the ApplyUpdatesAndResolveConflictsCommand on a directory where the 234 // Runs the ApplyUpdatesAndResolveConflictsCommand on a directory where the
237 // server is trying to delete a folder that has a recently added (and unsynced) 235 // server is trying to delete a folder that has a recently added (and unsynced)
238 // child. We expect the command to not apply the update because it is in a 236 // child. We expect the command to not apply the update because it is in a
239 // CONFLICT_HIERARCHY state. 237 // CONFLICT_HIERARCHY state.
240 TEST_F(ApplyUpdatesAndResolveConflictsCommandTest, 238 TEST_F(ApplyUpdatesAndResolveConflictsCommandTest,
241 HierarchyConflictDeleteNonEmptyDirectory) { 239 HierarchyConflictDeleteNonEmptyDirectory) {
242 // Create a server-deleted directory. 240 // Create a server-deleted directory.
243 { 241 {
244 // Create it as a child of root node. 242 // Create it as a child of root node.
245 int64 handle = 243 int64 handle = entry_factory_->CreateSyncedBookmarkItem("parent", true);
246 entry_factory_->CreateSyncedItem("parent", BOOKMARKS, true);
247 244
248 WriteTransaction trans(FROM_HERE, UNITTEST, directory()); 245 WriteTransaction trans(FROM_HERE, UNITTEST, directory());
249 MutableEntry entry(&trans, syncable::GET_BY_HANDLE, handle); 246 MutableEntry entry(&trans, syncable::GET_BY_HANDLE, handle);
250 ASSERT_TRUE(entry.good()); 247 ASSERT_TRUE(entry.good());
251 248
252 // Delete it on the server. 249 // Delete it on the server.
253 entry.Put(syncable::SERVER_VERSION, entry_factory_->GetNextRevision()); 250 entry.Put(syncable::SERVER_VERSION, entry_factory_->GetNextRevision());
254 entry.Put(syncable::IS_UNAPPLIED_UPDATE, true); 251 entry.Put(syncable::IS_UNAPPLIED_UPDATE, true);
255 entry.Put(syncable::SERVER_PARENT_ID, TestIdFactory::root()); 252 entry.Put(syncable::SERVER_PARENT_ID, TestIdFactory::root());
256 entry.Put(syncable::SERVER_IS_DEL, true); 253 entry.Put(syncable::SERVER_IS_DEL, true);
257 } 254 }
258 255
259 // Create a local child of the server-deleted directory. 256 // Create a local child of the server-deleted directory.
260 entry_factory_->CreateUnsyncedItem( 257 entry_factory_->CreateUnsyncedBookmarkItem(
261 TestIdFactory::MakeServer("child"), TestIdFactory::MakeServer("parent"), 258 TestIdFactory::MakeServer("child"), TestIdFactory::MakeServer("parent"),
262 "child", false, BOOKMARKS, NULL); 259 "child", false, NULL);
263 260
264 // The server's request to delete the directory must be ignored, otherwise our 261 // The server's request to delete the directory must be ignored, otherwise our
265 // unsynced new child would be orphaned. This is a hierarchy conflict. 262 // unsynced new child would be orphaned. This is a hierarchy conflict.
266 263
267 ExpectGroupToChange(apply_updates_command_, GROUP_UI); 264 ExpectGroupToChange(apply_updates_command_, GROUP_UI);
268 apply_updates_command_.ExecuteImpl(session()); 265 apply_updates_command_.ExecuteImpl(session());
269 266
270 const sessions::StatusController& status = session()->status_controller(); 267 const sessions::StatusController& status = session()->status_controller();
271 // This should count as a hierarchy conflict. 268 // This should count as a hierarchy conflict.
272 EXPECT_EQ(1, status.num_hierarchy_conflicts()); 269 EXPECT_EQ(1, status.num_hierarchy_conflicts());
(...skipping 137 matching lines...) Expand 10 before | Expand all | Expand 10 after
410 407
411 const sessions::StatusController& status = session()->status_controller(); 408 const sessions::StatusController& status = session()->status_controller();
412 EXPECT_EQ(1, status.num_encryption_conflicts()) 409 EXPECT_EQ(1, status.num_encryption_conflicts())
413 << "The updates that can't be decrypted should be in encryption " 410 << "The updates that can't be decrypted should be in encryption "
414 << "conflict"; 411 << "conflict";
415 EXPECT_EQ(1, status.num_updates_applied()) 412 EXPECT_EQ(1, status.num_updates_applied())
416 << "The undecryptable password update shouldn't be applied"; 413 << "The undecryptable password update shouldn't be applied";
417 } 414 }
418 415
419 } // namespace syncer 416 } // namespace syncer
OLDNEW
« no previous file with comments | « sync/engine/apply_control_data_updates_unittest.cc ('k') | sync/engine/build_commit_command.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698