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

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

Issue 11192071: sync: Merge apply updates and resolve conflicts (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 8 years, 2 months 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
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_command.h" 10 #include "sync/engine/apply_updates_command.h"
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after
75 DefaultBookmarkSpecifics(), 75 DefaultBookmarkSpecifics(),
76 root_server_id); 76 root_server_id);
77 entry_factory_->CreateUnappliedNewItemWithParent("child", 77 entry_factory_->CreateUnappliedNewItemWithParent("child",
78 DefaultBookmarkSpecifics(), 78 DefaultBookmarkSpecifics(),
79 "parent"); 79 "parent");
80 80
81 ExpectGroupToChange(apply_updates_command_, GROUP_UI); 81 ExpectGroupToChange(apply_updates_command_, GROUP_UI);
82 apply_updates_command_.ExecuteImpl(session()); 82 apply_updates_command_.ExecuteImpl(session());
83 83
84 const sessions::StatusController& status = session()->status_controller(); 84 const sessions::StatusController& status = session()->status_controller();
85 EXPECT_EQ(0, status.num_simple_conflicts())
86 << "Simple update shouldn't result in conflicts";
87 EXPECT_EQ(0, status.num_encryption_conflicts()) 85 EXPECT_EQ(0, status.num_encryption_conflicts())
88 << "Simple update shouldn't result in conflicts"; 86 << "Simple update shouldn't result in conflicts";
89 EXPECT_EQ(0, status.num_hierarchy_conflicts()) 87 EXPECT_EQ(0, status.num_hierarchy_conflicts())
90 << "Simple update shouldn't result in conflicts"; 88 << "Simple update shouldn't result in conflicts";
91 EXPECT_EQ(2, status.num_updates_applied()) 89 EXPECT_EQ(2, status.num_updates_applied())
92 << "All items should have been successfully applied"; 90 << "All items should have been successfully applied";
93 } 91 }
94 92
95 TEST_F(ApplyUpdatesCommandTest, UpdateWithChildrenBeforeParents) { 93 TEST_F(ApplyUpdatesCommandTest, UpdateWithChildrenBeforeParents) {
96 // Set a bunch of updates which are difficult to apply in the order 94 // Set a bunch of updates which are difficult to apply in the order
97 // they're received due to dependencies on other unseen items. 95 // they're received due to dependencies on other unseen items.
98 string root_server_id = syncable::GetNullId().GetServerId(); 96 string root_server_id = syncable::GetNullId().GetServerId();
99 entry_factory_->CreateUnappliedNewItemWithParent( 97 entry_factory_->CreateUnappliedNewItemWithParent(
100 "a_child_created_first", DefaultBookmarkSpecifics(), "parent"); 98 "a_child_created_first", DefaultBookmarkSpecifics(), "parent");
101 entry_factory_->CreateUnappliedNewItemWithParent( 99 entry_factory_->CreateUnappliedNewItemWithParent(
102 "x_child_created_first", DefaultBookmarkSpecifics(), "parent"); 100 "x_child_created_first", DefaultBookmarkSpecifics(), "parent");
103 entry_factory_->CreateUnappliedNewItemWithParent( 101 entry_factory_->CreateUnappliedNewItemWithParent(
104 "parent", DefaultBookmarkSpecifics(), root_server_id); 102 "parent", DefaultBookmarkSpecifics(), root_server_id);
105 entry_factory_->CreateUnappliedNewItemWithParent( 103 entry_factory_->CreateUnappliedNewItemWithParent(
106 "a_child_created_second", DefaultBookmarkSpecifics(), "parent"); 104 "a_child_created_second", DefaultBookmarkSpecifics(), "parent");
107 entry_factory_->CreateUnappliedNewItemWithParent( 105 entry_factory_->CreateUnappliedNewItemWithParent(
108 "x_child_created_second", DefaultBookmarkSpecifics(), "parent"); 106 "x_child_created_second", DefaultBookmarkSpecifics(), "parent");
109 107
110 ExpectGroupToChange(apply_updates_command_, GROUP_UI); 108 ExpectGroupToChange(apply_updates_command_, GROUP_UI);
111 apply_updates_command_.ExecuteImpl(session()); 109 apply_updates_command_.ExecuteImpl(session());
112 110
113 const sessions::StatusController& status = session()->status_controller(); 111 const sessions::StatusController& status = session()->status_controller();
114 EXPECT_EQ(0, status.num_simple_conflicts())
115 << "Simple update shouldn't result in conflicts, even if out-of-order";
116 EXPECT_EQ(5, status.num_updates_applied()) 112 EXPECT_EQ(5, status.num_updates_applied())
117 << "All updates should have been successfully applied"; 113 << "All updates should have been successfully applied";
118 } 114 }
119 115
120 // Runs the ApplyUpdatesCommand on an item that has both local and remote 116 // Runs the ApplyUpdatesCommand on an item that has both local and remote
121 // modifications (IS_UNSYNCED and IS_UNAPPLIED_UPDATE). We expect the command 117 // modifications (IS_UNSYNCED and IS_UNAPPLIED_UPDATE). We expect the command
122 // to detect that this update can't be applied because it is in a CONFLICT 118 // to detect that this update can't be applied because it is in a CONFLICT
123 // state. 119 // state.
124 TEST_F(ApplyUpdatesCommandTest, SimpleConflict) { 120 TEST_F(ApplyUpdatesCommandTest, SimpleConflict) {
125 entry_factory_->CreateUnappliedAndUnsyncedItem("item", BOOKMARKS); 121 entry_factory_->CreateUnappliedAndUnsyncedItem("item", BOOKMARKS);
126 122
127 ExpectGroupToChange(apply_updates_command_, GROUP_UI); 123 ExpectGroupToChange(apply_updates_command_, GROUP_UI);
128 apply_updates_command_.ExecuteImpl(session()); 124 apply_updates_command_.ExecuteImpl(session());
129 125
130 const sessions::StatusController& status = session()->status_controller(); 126 const sessions::StatusController& status = session()->status_controller();
131 EXPECT_EQ(1, status.num_simple_conflicts()) 127 EXPECT_EQ(1, status.num_server_overwrites())
132 << "Unsynced and unapplied item should be a simple conflict"; 128 << "Unsynced and unapplied item conflict should be resolved";
129 EXPECT_EQ(0, status.num_updates_applied())
130 << "Update should not be applied; we should override the server.";
133 } 131 }
134 132
135 // Runs the ApplyUpdatesCommand on an item that has both local and remote 133 // Runs the ApplyUpdatesCommand on an item that has both local and remote
136 // modifications *and* the remote modification cannot be applied without 134 // modifications *and* the remote modification cannot be applied without
137 // violating the tree constraints. We expect the command to detect that this 135 // violating the tree constraints. We expect the command to detect that this
138 // update can't be applied and that this situation can't be resolved with the 136 // update can't be applied and that this situation can't be resolved with the
139 // simple conflict processing logic; it is in a CONFLICT_HIERARCHY state. 137 // simple conflict processing logic; it is in a CONFLICT_HIERARCHY state.
140 TEST_F(ApplyUpdatesCommandTest, HierarchyAndSimpleConflict) { 138 TEST_F(ApplyUpdatesCommandTest, 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_->CreateUnappliedAndUnsyncedItem(
143 "orphaned_by_server", BOOKMARKS); 141 "orphaned_by_server", BOOKMARKS);
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
160 // An update that is both a simple conflict and a hierarchy conflict should be
161 // treated as a hierarchy conflict.
162 EXPECT_EQ(1, status.num_hierarchy_conflicts()); 157 EXPECT_EQ(1, status.num_hierarchy_conflicts());
163 EXPECT_EQ(0, status.num_simple_conflicts());
164 } 158 }
165 159
166 160
167 // Runs the ApplyUpdatesCommand on an item with remote modifications that would 161 // Runs the ApplyUpdatesCommand on an item with remote modifications that would
168 // create a directory loop if the update were applied. We expect the command to 162 // create a directory loop if the update were applied. We expect the command to
169 // detect that this update can't be applied because it is in a 163 // detect that this update can't be applied because it is in a
170 // CONFLICT_HIERARCHY state. 164 // CONFLICT_HIERARCHY state.
171 TEST_F(ApplyUpdatesCommandTest, HierarchyConflictDirectoryLoop) { 165 TEST_F(ApplyUpdatesCommandTest, HierarchyConflictDirectoryLoop) {
172 // Item 'X' locally has parent of 'root'. Server is updating it to have 166 // Item 'X' locally has parent of 'root'. Server is updating it to have
173 // parent of 'Y'. 167 // parent of 'Y'.
(...skipping 21 matching lines...) Expand all
195 // prevent the update from being applied and note that this is a hierarchy 189 // prevent the update from being applied and note that this is a hierarchy
196 // conflict. 190 // conflict.
197 191
198 ExpectGroupToChange(apply_updates_command_, GROUP_UI); 192 ExpectGroupToChange(apply_updates_command_, GROUP_UI);
199 apply_updates_command_.ExecuteImpl(session()); 193 apply_updates_command_.ExecuteImpl(session());
200 194
201 const sessions::StatusController& status = session()->status_controller(); 195 const sessions::StatusController& status = session()->status_controller();
202 196
203 // This should count as a hierarchy conflict. 197 // This should count as a hierarchy conflict.
204 EXPECT_EQ(1, status.num_hierarchy_conflicts()); 198 EXPECT_EQ(1, status.num_hierarchy_conflicts());
205 EXPECT_EQ(0, status.num_simple_conflicts());
206 } 199 }
207 200
208 // Runs the ApplyUpdatesCommand on a directory where the server sent us an 201 // Runs the ApplyUpdatesCommand on a directory where the server sent us an
209 // update to add a child to a locally deleted (and unsynced) parent. We expect 202 // update to add a child to a locally deleted (and unsynced) parent. We expect
210 // the command to not apply the update and to indicate the update is in a 203 // the command to not apply the update and to indicate the update is in a
211 // CONFLICT_HIERARCHY state. 204 // CONFLICT_HIERARCHY state.
212 TEST_F(ApplyUpdatesCommandTest, HierarchyConflictDeletedParent) { 205 TEST_F(ApplyUpdatesCommandTest, HierarchyConflictDeletedParent) {
213 // Create a locally deleted parent item. 206 // Create a locally deleted parent item.
214 int64 parent_handle; 207 int64 parent_handle;
215 entry_factory_->CreateUnsyncedItem( 208 entry_factory_->CreateUnsyncedItem(
(...skipping 11 matching lines...) Expand all
227 220
228 // The server's update may seem valid to some other client, but on this client 221 // The server's update may seem valid to some other client, but on this client
229 // that new item's parent no longer exists. The update should not be applied 222 // that new item's parent no longer exists. The update should not be applied
230 // and the update applicator should indicate this is a hierarchy conflict. 223 // and the update applicator should indicate this is a hierarchy conflict.
231 224
232 ExpectGroupToChange(apply_updates_command_, GROUP_UI); 225 ExpectGroupToChange(apply_updates_command_, GROUP_UI);
233 apply_updates_command_.ExecuteImpl(session()); 226 apply_updates_command_.ExecuteImpl(session());
234 227
235 const sessions::StatusController& status = session()->status_controller(); 228 const sessions::StatusController& status = session()->status_controller();
236 EXPECT_EQ(1, status.num_hierarchy_conflicts()); 229 EXPECT_EQ(1, status.num_hierarchy_conflicts());
237 EXPECT_EQ(0, status.num_simple_conflicts());
238 } 230 }
239 231
240 // Runs the ApplyUpdatesCommand on a directory where the server is trying to 232 // Runs the ApplyUpdatesCommand on a directory where the server is trying to
241 // delete a folder that has a recently added (and unsynced) child. We expect 233 // delete a folder that has a recently added (and unsynced) child. We expect
242 // the command to not apply the update because it is in a CONFLICT_HIERARCHY 234 // the command to not apply the update because it is in a CONFLICT_HIERARCHY
243 // state. 235 // state.
244 TEST_F(ApplyUpdatesCommandTest, HierarchyConflictDeleteNonEmptyDirectory) { 236 TEST_F(ApplyUpdatesCommandTest, HierarchyConflictDeleteNonEmptyDirectory) {
245 // Create a server-deleted directory. 237 // Create a server-deleted directory.
246 { 238 {
247 // Create it as a child of root node. 239 // Create it as a child of root node.
(...skipping 18 matching lines...) Expand all
266 258
267 // The server's request to delete the directory must be ignored, otherwise our 259 // The server's request to delete the directory must be ignored, otherwise our
268 // unsynced new child would be orphaned. This is a hierarchy conflict. 260 // unsynced new child would be orphaned. This is a hierarchy conflict.
269 261
270 ExpectGroupToChange(apply_updates_command_, GROUP_UI); 262 ExpectGroupToChange(apply_updates_command_, GROUP_UI);
271 apply_updates_command_.ExecuteImpl(session()); 263 apply_updates_command_.ExecuteImpl(session());
272 264
273 const sessions::StatusController& status = session()->status_controller(); 265 const sessions::StatusController& status = session()->status_controller();
274 // This should count as a hierarchy conflict. 266 // This should count as a hierarchy conflict.
275 EXPECT_EQ(1, status.num_hierarchy_conflicts()); 267 EXPECT_EQ(1, status.num_hierarchy_conflicts());
276 EXPECT_EQ(0, status.num_simple_conflicts());
277 } 268 }
278 269
279 // Runs the ApplyUpdatesCommand on a server-created item that has a locally 270 // Runs the ApplyUpdatesCommand on a server-created item that has a locally
280 // unknown parent. We expect the command to not apply the update because the 271 // unknown parent. We expect the command to not apply the update because the
281 // item is in a CONFLICT_HIERARCHY state. 272 // item is in a CONFLICT_HIERARCHY state.
282 TEST_F(ApplyUpdatesCommandTest, HierarchyConflictUnknownParent) { 273 TEST_F(ApplyUpdatesCommandTest, HierarchyConflictUnknownParent) {
283 // We shouldn't be able to do anything with either of these items. 274 // We shouldn't be able to do anything with either of these items.
284 entry_factory_->CreateUnappliedNewItemWithParent( 275 entry_factory_->CreateUnappliedNewItemWithParent(
285 "some_item", DefaultBookmarkSpecifics(), "unknown_parent"); 276 "some_item", DefaultBookmarkSpecifics(), "unknown_parent");
286 entry_factory_->CreateUnappliedNewItemWithParent( 277 entry_factory_->CreateUnappliedNewItemWithParent(
287 "some_other_item", DefaultBookmarkSpecifics(), "some_item"); 278 "some_other_item", DefaultBookmarkSpecifics(), "some_item");
288 279
289 ExpectGroupToChange(apply_updates_command_, GROUP_UI); 280 ExpectGroupToChange(apply_updates_command_, GROUP_UI);
290 apply_updates_command_.ExecuteImpl(session()); 281 apply_updates_command_.ExecuteImpl(session());
291 282
292 const sessions::StatusController& status = session()->status_controller(); 283 const sessions::StatusController& status = session()->status_controller();
293 EXPECT_EQ(0, status.num_simple_conflicts())
294 << "Updates with unknown parent should not be treated as 'simple'"
295 << " conflicts";
296 EXPECT_EQ(2, status.num_hierarchy_conflicts()) 284 EXPECT_EQ(2, status.num_hierarchy_conflicts())
297 << "All updates with an unknown ancestors should be in conflict"; 285 << "All updates with an unknown ancestors should be in conflict";
298 EXPECT_EQ(0, status.num_updates_applied()) 286 EXPECT_EQ(0, status.num_updates_applied())
299 << "No item with an unknown ancestor should be applied"; 287 << "No item with an unknown ancestor should be applied";
300 } 288 }
301 289
302 TEST_F(ApplyUpdatesCommandTest, ItemsBothKnownAndUnknown) { 290 TEST_F(ApplyUpdatesCommandTest, ItemsBothKnownAndUnknown) {
303 // See what happens when there's a mixture of good and bad updates. 291 // See what happens when there's a mixture of good and bad updates.
304 string root_server_id = syncable::GetNullId().GetServerId(); 292 string root_server_id = syncable::GetNullId().GetServerId();
305 entry_factory_->CreateUnappliedNewItemWithParent( 293 entry_factory_->CreateUnappliedNewItemWithParent(
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
343 data.set_origin("http://example.com"); 331 data.set_origin("http://example.com");
344 332
345 cryptographer->Encrypt(data, 333 cryptographer->Encrypt(data,
346 specifics.mutable_password()->mutable_encrypted()); 334 specifics.mutable_password()->mutable_encrypted());
347 entry_factory_->CreateUnappliedNewItem("item", specifics, false); 335 entry_factory_->CreateUnappliedNewItem("item", specifics, false);
348 336
349 ExpectGroupToChange(apply_updates_command_, GROUP_PASSWORD); 337 ExpectGroupToChange(apply_updates_command_, GROUP_PASSWORD);
350 apply_updates_command_.ExecuteImpl(session()); 338 apply_updates_command_.ExecuteImpl(session());
351 339
352 const sessions::StatusController& status = session()->status_controller(); 340 const sessions::StatusController& status = session()->status_controller();
353 EXPECT_EQ(0, status.num_simple_conflicts())
354 << "No update should be in conflict because they're all decryptable";
355 EXPECT_EQ(1, status.num_updates_applied()) 341 EXPECT_EQ(1, status.num_updates_applied())
356 << "The updates that can be decrypted should be applied"; 342 << "The updates that can be decrypted should be applied";
357 } 343 }
358 344
359 TEST_F(ApplyUpdatesCommandTest, UndecryptableData) { 345 TEST_F(ApplyUpdatesCommandTest, UndecryptableData) {
360 // Undecryptable updates should not be applied. 346 // Undecryptable updates should not be applied.
361 sync_pb::EntitySpecifics encrypted_bookmark; 347 sync_pb::EntitySpecifics encrypted_bookmark;
362 encrypted_bookmark.mutable_encrypted(); 348 encrypted_bookmark.mutable_encrypted();
363 AddDefaultFieldValue(BOOKMARKS, &encrypted_bookmark); 349 AddDefaultFieldValue(BOOKMARKS, &encrypted_bookmark);
364 string root_server_id = syncable::GetNullId().GetServerId(); 350 string root_server_id = syncable::GetNullId().GetServerId();
365 entry_factory_->CreateUnappliedNewItemWithParent( 351 entry_factory_->CreateUnappliedNewItemWithParent(
366 "folder", encrypted_bookmark, root_server_id); 352 "folder", encrypted_bookmark, root_server_id);
367 entry_factory_->CreateUnappliedNewItem("item2", encrypted_bookmark, false); 353 entry_factory_->CreateUnappliedNewItem("item2", encrypted_bookmark, false);
368 sync_pb::EntitySpecifics encrypted_password; 354 sync_pb::EntitySpecifics encrypted_password;
369 encrypted_password.mutable_password(); 355 encrypted_password.mutable_password();
370 entry_factory_->CreateUnappliedNewItem("item3", encrypted_password, false); 356 entry_factory_->CreateUnappliedNewItem("item3", encrypted_password, false);
371 357
372 ExpectGroupsToChange(apply_updates_command_, GROUP_UI, GROUP_PASSWORD); 358 ExpectGroupsToChange(apply_updates_command_, GROUP_UI, GROUP_PASSWORD);
373 apply_updates_command_.ExecuteImpl(session()); 359 apply_updates_command_.ExecuteImpl(session());
374 360
375 const sessions::StatusController& status = session()->status_controller(); 361 const sessions::StatusController& status = session()->status_controller();
376 EXPECT_TRUE(status.HasConflictingUpdates())
377 << "Updates that can't be decrypted should trigger the syncer to have "
378 << "conflicting updates.";
379 EXPECT_EQ(0, status.num_simple_conflicts())
380 << "Updates that can't be decrypted should not be in regular conflict";
381 EXPECT_EQ(3, status.num_encryption_conflicts()) 362 EXPECT_EQ(3, status.num_encryption_conflicts())
382 << "Updates that can't be decrypted should be in encryption conflict"; 363 << "Updates that can't be decrypted should be in encryption conflict";
383 EXPECT_EQ(0, status.num_updates_applied()) 364 EXPECT_EQ(0, status.num_updates_applied())
384 << "No update that can't be decrypted should be applied"; 365 << "No update that can't be decrypted should be applied";
385 } 366 }
386 367
387 TEST_F(ApplyUpdatesCommandTest, SomeUndecryptablePassword) { 368 TEST_F(ApplyUpdatesCommandTest, SomeUndecryptablePassword) {
388 Cryptographer* cryptographer; 369 Cryptographer* cryptographer;
389 // Only decryptable password updates should be applied. 370 // Only decryptable password updates should be applied.
390 { 371 {
(...skipping 24 matching lines...) Expand all
415 396
416 other_cryptographer.Encrypt(data, 397 other_cryptographer.Encrypt(data,
417 specifics.mutable_password()->mutable_encrypted()); 398 specifics.mutable_password()->mutable_encrypted());
418 entry_factory_->CreateUnappliedNewItem("item2", specifics, false); 399 entry_factory_->CreateUnappliedNewItem("item2", specifics, false);
419 } 400 }
420 401
421 ExpectGroupToChange(apply_updates_command_, GROUP_PASSWORD); 402 ExpectGroupToChange(apply_updates_command_, GROUP_PASSWORD);
422 apply_updates_command_.ExecuteImpl(session()); 403 apply_updates_command_.ExecuteImpl(session());
423 404
424 const sessions::StatusController& status = session()->status_controller(); 405 const sessions::StatusController& status = session()->status_controller();
425 EXPECT_TRUE(status.HasConflictingUpdates())
426 << "Updates that can't be decrypted should trigger the syncer to have "
427 << "conflicting updates.";
428 EXPECT_EQ(0, status.num_simple_conflicts())
429 << "The updates that can't be decrypted should not be in regular "
430 << "conflict";
431 EXPECT_EQ(1, status.num_encryption_conflicts()) 406 EXPECT_EQ(1, status.num_encryption_conflicts())
432 << "The updates that can't be decrypted should be in encryption " 407 << "The updates that can't be decrypted should be in encryption "
433 << "conflict"; 408 << "conflict";
434 EXPECT_EQ(1, status.num_updates_applied()) 409 EXPECT_EQ(1, status.num_updates_applied())
435 << "The undecryptable password update shouldn't be applied"; 410 << "The undecryptable password update shouldn't be applied";
436 } 411 }
437 412
438 } // namespace syncer 413 } // namespace syncer
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698