| OLD | NEW |
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 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 "sync/engine/directory_update_handler.h" | 5 #include "components/sync/engine_impl/directory_update_handler.h" |
| 6 | 6 |
| 7 #include <stdint.h> | 7 #include <stdint.h> |
| 8 | 8 |
| 9 #include <memory> | 9 #include <memory> |
| 10 #include <set> | 10 #include <set> |
| 11 #include <string> | 11 #include <string> |
| 12 #include <utility> | 12 #include <utility> |
| 13 | 13 |
| 14 #include "base/compiler_specific.h" | 14 #include "base/compiler_specific.h" |
| 15 #include "base/macros.h" | 15 #include "base/macros.h" |
| 16 #include "base/memory/ptr_util.h" | 16 #include "base/memory/ptr_util.h" |
| 17 #include "base/message_loop/message_loop.h" | 17 #include "base/message_loop/message_loop.h" |
| 18 #include "sync/engine/syncer_proto_util.h" | 18 #include "components/sync/base/attachment_id_proto.h" |
| 19 #include "sync/internal_api/public/base/attachment_id_proto.h" | 19 #include "components/sync/base/model_type.h" |
| 20 #include "sync/internal_api/public/base/model_type.h" | 20 #include "components/sync/core/test/test_entry_factory.h" |
| 21 #include "sync/internal_api/public/test/test_entry_factory.h" | 21 #include "components/sync/engine_impl/syncer_proto_util.h" |
| 22 #include "sync/protocol/sync.pb.h" | 22 #include "components/sync/protocol/sync.pb.h" |
| 23 #include "sync/sessions/directory_type_debug_info_emitter.h" | 23 #include "components/sync/sessions_impl/directory_type_debug_info_emitter.h" |
| 24 #include "sync/sessions/status_controller.h" | 24 #include "components/sync/sessions_impl/status_controller.h" |
| 25 #include "sync/syncable/directory.h" | 25 #include "components/sync/syncable/directory.h" |
| 26 #include "sync/syncable/entry.h" | 26 #include "components/sync/syncable/entry.h" |
| 27 #include "sync/syncable/mutable_entry.h" | 27 #include "components/sync/syncable/mutable_entry.h" |
| 28 #include "sync/syncable/syncable_model_neutral_write_transaction.h" | 28 #include "components/sync/syncable/syncable_model_neutral_write_transaction.h" |
| 29 #include "sync/syncable/syncable_proto_util.h" | 29 #include "components/sync/syncable/syncable_proto_util.h" |
| 30 #include "sync/syncable/syncable_read_transaction.h" | 30 #include "components/sync/syncable/syncable_read_transaction.h" |
| 31 #include "sync/syncable/syncable_write_transaction.h" | 31 #include "components/sync/syncable/syncable_write_transaction.h" |
| 32 #include "sync/test/engine/fake_model_worker.h" | 32 #include "components/sync/test/engine/fake_model_worker.h" |
| 33 #include "sync/test/engine/test_directory_setter_upper.h" | 33 #include "components/sync/test/engine/test_directory_setter_upper.h" |
| 34 #include "sync/test/engine/test_id_factory.h" | 34 #include "components/sync/test/engine/test_id_factory.h" |
| 35 #include "sync/test/engine/test_syncable_utils.h" | 35 #include "components/sync/test/engine/test_syncable_utils.h" |
| 36 #include "testing/gtest/include/gtest/gtest.h" | 36 #include "testing/gtest/include/gtest/gtest.h" |
| 37 | 37 |
| 38 namespace syncer { | 38 namespace syncer { |
| 39 | 39 |
| 40 using syncable::Id; | 40 using syncable::Id; |
| 41 using syncable::UNITTEST; | 41 using syncable::UNITTEST; |
| 42 | 42 |
| 43 static const int64_t kDefaultVersion = 1000; | 43 static const int64_t kDefaultVersion = 1000; |
| 44 | 44 |
| 45 // A test harness for tests that focus on processing updates. | 45 // A test harness for tests that focus on processing updates. |
| 46 // | 46 // |
| 47 // Update processing is what occurs when we first download updates. It converts | 47 // Update processing is what occurs when we first download updates. It converts |
| 48 // the received protobuf message into information in the syncable::Directory. | 48 // the received protobuf message into information in the syncable::Directory. |
| 49 // Any invalid or redundant updates will be dropped at this point. | 49 // Any invalid or redundant updates will be dropped at this point. |
| 50 class DirectoryUpdateHandlerProcessUpdateTest : public ::testing::Test { | 50 class DirectoryUpdateHandlerProcessUpdateTest : public ::testing::Test { |
| 51 public: | 51 public: |
| 52 DirectoryUpdateHandlerProcessUpdateTest() | 52 DirectoryUpdateHandlerProcessUpdateTest() |
| 53 : ui_worker_(new FakeModelWorker(GROUP_UI)) { | 53 : ui_worker_(new FakeModelWorker(GROUP_UI)) {} |
| 54 } | |
| 55 | 54 |
| 56 ~DirectoryUpdateHandlerProcessUpdateTest() override {} | 55 ~DirectoryUpdateHandlerProcessUpdateTest() override {} |
| 57 | 56 |
| 58 void SetUp() override { dir_maker_.SetUp(); } | 57 void SetUp() override { dir_maker_.SetUp(); } |
| 59 | 58 |
| 60 void TearDown() override { dir_maker_.TearDown(); } | 59 void TearDown() override { dir_maker_.TearDown(); } |
| 61 | 60 |
| 62 syncable::Directory* dir() { | 61 syncable::Directory* dir() { return dir_maker_.directory(); } |
| 63 return dir_maker_.directory(); | |
| 64 } | |
| 65 | 62 |
| 66 protected: | 63 protected: |
| 67 std::unique_ptr<sync_pb::SyncEntity> CreateUpdate(const std::string& id, | 64 std::unique_ptr<sync_pb::SyncEntity> CreateUpdate(const std::string& id, |
| 68 const std::string& parent, | 65 const std::string& parent, |
| 69 const ModelType& type); | 66 const ModelType& type); |
| 70 | 67 |
| 71 // This exists mostly to give tests access to the protected member function. | 68 // This exists mostly to give tests access to the protected member function. |
| 72 // Warning: This takes the syncable directory lock. | 69 // Warning: This takes the syncable directory lock. |
| 73 void UpdateSyncEntities( | 70 void UpdateSyncEntities(DirectoryUpdateHandler* handler, |
| 74 DirectoryUpdateHandler* handler, | 71 const SyncEntityList& applicable_updates, |
| 75 const SyncEntityList& applicable_updates, | 72 sessions::StatusController* status); |
| 76 sessions::StatusController* status); | |
| 77 | 73 |
| 78 // Another function to access private member functions. | 74 // Another function to access private member functions. |
| 79 void UpdateProgressMarkers( | 75 void UpdateProgressMarkers(DirectoryUpdateHandler* handler, |
| 80 DirectoryUpdateHandler* handler, | 76 const sync_pb::DataTypeProgressMarker& progress); |
| 81 const sync_pb::DataTypeProgressMarker& progress); | |
| 82 | 77 |
| 83 scoped_refptr<FakeModelWorker> ui_worker() { | 78 scoped_refptr<FakeModelWorker> ui_worker() { return ui_worker_; } |
| 84 return ui_worker_; | |
| 85 } | |
| 86 | 79 |
| 87 bool EntryExists(const std::string& id) { | 80 bool EntryExists(const std::string& id) { |
| 88 syncable::ReadTransaction trans(FROM_HERE, dir()); | 81 syncable::ReadTransaction trans(FROM_HERE, dir()); |
| 89 syncable::Entry e(&trans, syncable::GET_BY_ID, | 82 syncable::Entry e(&trans, syncable::GET_BY_ID, Id::CreateFromServerId(id)); |
| 90 Id::CreateFromServerId(id)); | |
| 91 return e.good() && !e.GetIsDel(); | 83 return e.good() && !e.GetIsDel(); |
| 92 } | 84 } |
| 93 | 85 |
| 94 bool TypeRootExists(ModelType model_type) { | 86 bool TypeRootExists(ModelType model_type) { |
| 95 return dir()->InitialSyncEndedForType(model_type); | 87 return dir()->InitialSyncEndedForType(model_type); |
| 96 } | 88 } |
| 97 | 89 |
| 98 protected: | 90 protected: |
| 99 // Used in the construction of DirectoryTypeDebugInfoEmitters. | 91 // Used in the construction of DirectoryTypeDebugInfoEmitters. |
| 100 base::ObserverList<TypeDebugInfoObserver> type_observers_; | 92 base::ObserverList<TypeDebugInfoObserver> type_observers_; |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 141 DirectoryUpdateHandler handler(dir(), BOOKMARKS, ui_worker(), &emitter); | 133 DirectoryUpdateHandler handler(dir(), BOOKMARKS, ui_worker(), &emitter); |
| 142 sync_pb::GetUpdatesResponse gu_response; | 134 sync_pb::GetUpdatesResponse gu_response; |
| 143 sessions::StatusController status; | 135 sessions::StatusController status; |
| 144 | 136 |
| 145 // Add a bookmark item to the update message. | 137 // Add a bookmark item to the update message. |
| 146 std::string root = Id::GetRoot().GetServerId(); | 138 std::string root = Id::GetRoot().GetServerId(); |
| 147 Id server_id = Id::CreateFromServerId("b1"); | 139 Id server_id = Id::CreateFromServerId("b1"); |
| 148 std::unique_ptr<sync_pb::SyncEntity> e = | 140 std::unique_ptr<sync_pb::SyncEntity> e = |
| 149 CreateUpdate(SyncableIdToProto(server_id), root, BOOKMARKS); | 141 CreateUpdate(SyncableIdToProto(server_id), root, BOOKMARKS); |
| 150 e->set_originator_cache_guid( | 142 e->set_originator_cache_guid( |
| 151 std::string(kCacheGuid, arraysize(kCacheGuid)-1)); | 143 std::string(kCacheGuid, arraysize(kCacheGuid) - 1)); |
| 152 Id client_id = Id::CreateFromClientString("-2"); | 144 Id client_id = Id::CreateFromClientString("-2"); |
| 153 e->set_originator_client_item_id(client_id.GetServerId()); | 145 e->set_originator_client_item_id(client_id.GetServerId()); |
| 154 e->set_position_in_parent(0); | 146 e->set_position_in_parent(0); |
| 155 | 147 |
| 156 // Add it to the applicable updates list. | 148 // Add it to the applicable updates list. |
| 157 SyncEntityList bookmark_updates; | 149 SyncEntityList bookmark_updates; |
| 158 bookmark_updates.push_back(e.get()); | 150 bookmark_updates.push_back(e.get()); |
| 159 | 151 |
| 160 // Process the update. | 152 // Process the update. |
| 161 UpdateSyncEntities(&handler, bookmark_updates, &status); | 153 UpdateSyncEntities(&handler, bookmark_updates, &status); |
| (...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 254 | 246 |
| 255 sync_pb::DataTypeProgressMarker saved; | 247 sync_pb::DataTypeProgressMarker saved; |
| 256 dir()->GetDownloadProgress(BOOKMARKS, &saved); | 248 dir()->GetDownloadProgress(BOOKMARKS, &saved); |
| 257 | 249 |
| 258 EXPECT_EQ(progress.token(), saved.token()); | 250 EXPECT_EQ(progress.token(), saved.token()); |
| 259 EXPECT_EQ(progress.data_type_id(), saved.data_type_id()); | 251 EXPECT_EQ(progress.data_type_id(), saved.data_type_id()); |
| 260 } | 252 } |
| 261 | 253 |
| 262 TEST_F(DirectoryUpdateHandlerProcessUpdateTest, GarbageCollectionByVersion) { | 254 TEST_F(DirectoryUpdateHandlerProcessUpdateTest, GarbageCollectionByVersion) { |
| 263 DirectoryTypeDebugInfoEmitter emitter(SYNCED_NOTIFICATIONS, &type_observers_); | 255 DirectoryTypeDebugInfoEmitter emitter(SYNCED_NOTIFICATIONS, &type_observers_); |
| 264 DirectoryUpdateHandler handler(dir(), SYNCED_NOTIFICATIONS, | 256 DirectoryUpdateHandler handler(dir(), SYNCED_NOTIFICATIONS, ui_worker(), |
| 265 ui_worker(), &emitter); | 257 &emitter); |
| 266 sessions::StatusController status; | 258 sessions::StatusController status; |
| 267 | 259 |
| 268 sync_pb::DataTypeProgressMarker progress; | 260 sync_pb::DataTypeProgressMarker progress; |
| 269 progress.set_data_type_id( | 261 progress.set_data_type_id( |
| 270 GetSpecificsFieldNumberFromModelType(SYNCED_NOTIFICATIONS)); | 262 GetSpecificsFieldNumberFromModelType(SYNCED_NOTIFICATIONS)); |
| 271 progress.set_token("token"); | 263 progress.set_token("token"); |
| 272 progress.mutable_gc_directive()->set_version_watermark(kDefaultVersion + 10); | 264 progress.mutable_gc_directive()->set_version_watermark(kDefaultVersion + 10); |
| 273 | 265 |
| 274 sync_pb::DataTypeContext context; | 266 sync_pb::DataTypeContext context; |
| 275 context.set_data_type_id( | 267 context.set_data_type_id( |
| 276 GetSpecificsFieldNumberFromModelType(SYNCED_NOTIFICATIONS)); | 268 GetSpecificsFieldNumberFromModelType(SYNCED_NOTIFICATIONS)); |
| 277 context.set_context("context"); | 269 context.set_context("context"); |
| 278 context.set_version(1); | 270 context.set_version(1); |
| 279 | 271 |
| 280 std::unique_ptr<sync_pb::SyncEntity> e1 = | 272 std::unique_ptr<sync_pb::SyncEntity> e1 = |
| 281 CreateUpdate(SyncableIdToProto(Id::CreateFromServerId("e1")), "", | 273 CreateUpdate(SyncableIdToProto(Id::CreateFromServerId("e1")), "", |
| 282 SYNCED_NOTIFICATIONS); | 274 SYNCED_NOTIFICATIONS); |
| 283 | 275 |
| 284 std::unique_ptr<sync_pb::SyncEntity> e2 = | 276 std::unique_ptr<sync_pb::SyncEntity> e2 = |
| 285 CreateUpdate(SyncableIdToProto(Id::CreateFromServerId("e2")), "", | 277 CreateUpdate(SyncableIdToProto(Id::CreateFromServerId("e2")), "", |
| 286 SYNCED_NOTIFICATIONS); | 278 SYNCED_NOTIFICATIONS); |
| 287 e2->set_version(kDefaultVersion + 100); | 279 e2->set_version(kDefaultVersion + 100); |
| 288 | 280 |
| 289 // Add to the applicable updates list. | 281 // Add to the applicable updates list. |
| 290 SyncEntityList updates; | 282 SyncEntityList updates; |
| 291 updates.push_back(e1.get()); | 283 updates.push_back(e1.get()); |
| 292 updates.push_back(e2.get()); | 284 updates.push_back(e2.get()); |
| 293 | 285 |
| 294 // Process and apply updates. | 286 // Process and apply updates. |
| 295 EXPECT_EQ( | 287 EXPECT_EQ(SYNCER_OK, handler.ProcessGetUpdatesResponse(progress, context, |
| 296 SYNCER_OK, | 288 updates, &status)); |
| 297 handler.ProcessGetUpdatesResponse(progress, context, updates, &status)); | |
| 298 handler.ApplyUpdates(&status); | 289 handler.ApplyUpdates(&status); |
| 299 | 290 |
| 300 // Verify none is deleted because they are unapplied during GC. | 291 // Verify none is deleted because they are unapplied during GC. |
| 301 EXPECT_TRUE(TypeRootExists(SYNCED_NOTIFICATIONS)); | 292 EXPECT_TRUE(TypeRootExists(SYNCED_NOTIFICATIONS)); |
| 302 EXPECT_TRUE(EntryExists(e1->id_string())); | 293 EXPECT_TRUE(EntryExists(e1->id_string())); |
| 303 EXPECT_TRUE(EntryExists(e2->id_string())); | 294 EXPECT_TRUE(EntryExists(e2->id_string())); |
| 304 | 295 |
| 305 // Process and apply again. Old entry is deleted but not root. | 296 // Process and apply again. Old entry is deleted but not root. |
| 306 progress.mutable_gc_directive()->set_version_watermark(kDefaultVersion + 20); | 297 progress.mutable_gc_directive()->set_version_watermark(kDefaultVersion + 20); |
| 307 EXPECT_EQ(SYNCER_OK, | 298 EXPECT_EQ(SYNCER_OK, handler.ProcessGetUpdatesResponse( |
| 308 handler.ProcessGetUpdatesResponse( | 299 progress, context, SyncEntityList(), &status)); |
| 309 progress, context, SyncEntityList(), &status)); | |
| 310 handler.ApplyUpdates(&status); | 300 handler.ApplyUpdates(&status); |
| 311 EXPECT_FALSE(EntryExists(e1->id_string())); | 301 EXPECT_FALSE(EntryExists(e1->id_string())); |
| 312 EXPECT_TRUE(EntryExists(e2->id_string())); | 302 EXPECT_TRUE(EntryExists(e2->id_string())); |
| 313 } | 303 } |
| 314 | 304 |
| 315 TEST_F(DirectoryUpdateHandlerProcessUpdateTest, ContextVersion) { | 305 TEST_F(DirectoryUpdateHandlerProcessUpdateTest, ContextVersion) { |
| 316 DirectoryTypeDebugInfoEmitter emitter(SYNCED_NOTIFICATIONS, &type_observers_); | 306 DirectoryTypeDebugInfoEmitter emitter(SYNCED_NOTIFICATIONS, &type_observers_); |
| 317 DirectoryUpdateHandler handler(dir(), SYNCED_NOTIFICATIONS, | 307 DirectoryUpdateHandler handler(dir(), SYNCED_NOTIFICATIONS, ui_worker(), |
| 318 ui_worker(), &emitter); | 308 &emitter); |
| 319 sessions::StatusController status; | 309 sessions::StatusController status; |
| 320 int field_number = GetSpecificsFieldNumberFromModelType(SYNCED_NOTIFICATIONS); | 310 int field_number = GetSpecificsFieldNumberFromModelType(SYNCED_NOTIFICATIONS); |
| 321 | 311 |
| 322 sync_pb::DataTypeProgressMarker progress; | 312 sync_pb::DataTypeProgressMarker progress; |
| 323 progress.set_data_type_id( | 313 progress.set_data_type_id( |
| 324 GetSpecificsFieldNumberFromModelType(SYNCED_NOTIFICATIONS)); | 314 GetSpecificsFieldNumberFromModelType(SYNCED_NOTIFICATIONS)); |
| 325 progress.set_token("token"); | 315 progress.set_token("token"); |
| 326 | 316 |
| 327 sync_pb::DataTypeContext old_context; | 317 sync_pb::DataTypeContext old_context; |
| 328 old_context.set_version(1); | 318 old_context.set_version(1); |
| 329 old_context.set_context("data"); | 319 old_context.set_context("data"); |
| 330 old_context.set_data_type_id(field_number); | 320 old_context.set_data_type_id(field_number); |
| 331 | 321 |
| 332 std::unique_ptr<sync_pb::SyncEntity> e1 = | 322 std::unique_ptr<sync_pb::SyncEntity> e1 = |
| 333 CreateUpdate(SyncableIdToProto(Id::CreateFromServerId("e1")), "", | 323 CreateUpdate(SyncableIdToProto(Id::CreateFromServerId("e1")), "", |
| 334 SYNCED_NOTIFICATIONS); | 324 SYNCED_NOTIFICATIONS); |
| 335 | 325 |
| 336 SyncEntityList updates; | 326 SyncEntityList updates; |
| 337 updates.push_back(e1.get()); | 327 updates.push_back(e1.get()); |
| 338 | 328 |
| 339 // The first response should be processed fine. | 329 // The first response should be processed fine. |
| 340 EXPECT_EQ(SYNCER_OK, | 330 EXPECT_EQ(SYNCER_OK, handler.ProcessGetUpdatesResponse(progress, old_context, |
| 341 handler.ProcessGetUpdatesResponse( | 331 updates, &status)); |
| 342 progress, old_context, updates, &status)); | |
| 343 handler.ApplyUpdates(&status); | 332 handler.ApplyUpdates(&status); |
| 344 | 333 |
| 345 // The PREFERENCES root should be auto-created. | 334 // The PREFERENCES root should be auto-created. |
| 346 EXPECT_TRUE(TypeRootExists(SYNCED_NOTIFICATIONS)); | 335 EXPECT_TRUE(TypeRootExists(SYNCED_NOTIFICATIONS)); |
| 347 | 336 |
| 348 EXPECT_TRUE(EntryExists(e1->id_string())); | 337 EXPECT_TRUE(EntryExists(e1->id_string())); |
| 349 | 338 |
| 350 { | 339 { |
| 351 sync_pb::DataTypeContext dir_context; | 340 sync_pb::DataTypeContext dir_context; |
| 352 syncable::ReadTransaction trans(FROM_HERE, dir()); | 341 syncable::ReadTransaction trans(FROM_HERE, dir()); |
| 353 trans.directory()->GetDataTypeContext( | 342 trans.directory()->GetDataTypeContext(&trans, SYNCED_NOTIFICATIONS, |
| 354 &trans, SYNCED_NOTIFICATIONS, &dir_context); | 343 &dir_context); |
| 355 EXPECT_EQ(old_context.SerializeAsString(), dir_context.SerializeAsString()); | 344 EXPECT_EQ(old_context.SerializeAsString(), dir_context.SerializeAsString()); |
| 356 } | 345 } |
| 357 | 346 |
| 358 sync_pb::DataTypeContext new_context; | 347 sync_pb::DataTypeContext new_context; |
| 359 new_context.set_version(0); | 348 new_context.set_version(0); |
| 360 new_context.set_context("old"); | 349 new_context.set_context("old"); |
| 361 new_context.set_data_type_id(field_number); | 350 new_context.set_data_type_id(field_number); |
| 362 | 351 |
| 363 std::unique_ptr<sync_pb::SyncEntity> e2 = | 352 std::unique_ptr<sync_pb::SyncEntity> e2 = |
| 364 CreateUpdate(SyncableIdToProto(Id::CreateFromServerId("e2")), "", | 353 CreateUpdate(SyncableIdToProto(Id::CreateFromServerId("e2")), "", |
| 365 SYNCED_NOTIFICATIONS); | 354 SYNCED_NOTIFICATIONS); |
| 366 updates.clear(); | 355 updates.clear(); |
| 367 updates.push_back(e2.get()); | 356 updates.push_back(e2.get()); |
| 368 | 357 |
| 369 // The second response, with an old context version, should result in an | 358 // The second response, with an old context version, should result in an |
| 370 // error and the updates should be dropped. | 359 // error and the updates should be dropped. |
| 371 EXPECT_EQ(DATATYPE_TRIGGERED_RETRY, | 360 EXPECT_EQ(DATATYPE_TRIGGERED_RETRY, |
| 372 handler.ProcessGetUpdatesResponse( | 361 handler.ProcessGetUpdatesResponse(progress, new_context, updates, |
| 373 progress, new_context, updates, &status)); | 362 &status)); |
| 374 handler.ApplyUpdates(&status); | 363 handler.ApplyUpdates(&status); |
| 375 | 364 |
| 376 EXPECT_FALSE(EntryExists(e2->id_string())); | 365 EXPECT_FALSE(EntryExists(e2->id_string())); |
| 377 | 366 |
| 378 { | 367 { |
| 379 sync_pb::DataTypeContext dir_context; | 368 sync_pb::DataTypeContext dir_context; |
| 380 syncable::ReadTransaction trans(FROM_HERE, dir()); | 369 syncable::ReadTransaction trans(FROM_HERE, dir()); |
| 381 trans.directory()->GetDataTypeContext( | 370 trans.directory()->GetDataTypeContext(&trans, SYNCED_NOTIFICATIONS, |
| 382 &trans, SYNCED_NOTIFICATIONS, &dir_context); | 371 &dir_context); |
| 383 EXPECT_EQ(old_context.SerializeAsString(), dir_context.SerializeAsString()); | 372 EXPECT_EQ(old_context.SerializeAsString(), dir_context.SerializeAsString()); |
| 384 } | 373 } |
| 385 } | 374 } |
| 386 | 375 |
| 387 // See that updates containing attachment metadata are applied | 376 // See that updates containing attachment metadata are applied |
| 388 // (i.e. server_attachment_metadata is copied to attachment_metadata). | 377 // (i.e. server_attachment_metadata is copied to attachment_metadata). |
| 389 TEST_F(DirectoryUpdateHandlerProcessUpdateTest, | 378 TEST_F(DirectoryUpdateHandlerProcessUpdateTest, |
| 390 ProcessAndApplyUpdatesWithAttachments) { | 379 ProcessAndApplyUpdatesWithAttachments) { |
| 391 DirectoryTypeDebugInfoEmitter emitter(ARTICLES, &type_observers_); | 380 DirectoryTypeDebugInfoEmitter emitter(ARTICLES, &type_observers_); |
| 392 DirectoryUpdateHandler handler(dir(), ARTICLES, ui_worker(), &emitter); | 381 DirectoryUpdateHandler handler(dir(), ARTICLES, ui_worker(), &emitter); |
| (...skipping 11 matching lines...) Expand all Loading... |
| 404 | 393 |
| 405 std::unique_ptr<sync_pb::SyncEntity> e1 = CreateUpdate( | 394 std::unique_ptr<sync_pb::SyncEntity> e1 = CreateUpdate( |
| 406 SyncableIdToProto(Id::CreateFromServerId("e1")), "", ARTICLES); | 395 SyncableIdToProto(Id::CreateFromServerId("e1")), "", ARTICLES); |
| 407 sync_pb::AttachmentIdProto* attachment_id = e1->add_attachment_id(); | 396 sync_pb::AttachmentIdProto* attachment_id = e1->add_attachment_id(); |
| 408 *attachment_id = CreateAttachmentIdProto(0, 0); | 397 *attachment_id = CreateAttachmentIdProto(0, 0); |
| 409 | 398 |
| 410 SyncEntityList updates; | 399 SyncEntityList updates; |
| 411 updates.push_back(e1.get()); | 400 updates.push_back(e1.get()); |
| 412 | 401 |
| 413 // Process and apply updates. | 402 // Process and apply updates. |
| 414 EXPECT_EQ( | 403 EXPECT_EQ(SYNCER_OK, handler.ProcessGetUpdatesResponse(progress, context, |
| 415 SYNCER_OK, | 404 updates, &status)); |
| 416 handler.ProcessGetUpdatesResponse(progress, context, updates, &status)); | |
| 417 handler.ApplyUpdates(&status); | 405 handler.ApplyUpdates(&status); |
| 418 | 406 |
| 419 ASSERT_TRUE(TypeRootExists(ARTICLES)); | 407 ASSERT_TRUE(TypeRootExists(ARTICLES)); |
| 420 ASSERT_TRUE(EntryExists(e1->id_string())); | 408 ASSERT_TRUE(EntryExists(e1->id_string())); |
| 421 { | 409 { |
| 422 syncable::ReadTransaction trans(FROM_HERE, dir()); | 410 syncable::ReadTransaction trans(FROM_HERE, dir()); |
| 423 syncable::Entry e(&trans, | 411 syncable::Entry e(&trans, syncable::GET_BY_ID, |
| 424 syncable::GET_BY_ID, | |
| 425 Id::CreateFromServerId(e1->id_string())); | 412 Id::CreateFromServerId(e1->id_string())); |
| 426 | 413 |
| 427 // See that the attachment_metadata is correct. | 414 // See that the attachment_metadata is correct. |
| 428 sync_pb::AttachmentMetadata attachment_metadata = e.GetAttachmentMetadata(); | 415 sync_pb::AttachmentMetadata attachment_metadata = e.GetAttachmentMetadata(); |
| 429 ASSERT_EQ(1, attachment_metadata.record_size()); | 416 ASSERT_EQ(1, attachment_metadata.record_size()); |
| 430 ASSERT_EQ(attachment_id->SerializeAsString(), | 417 ASSERT_EQ(attachment_id->SerializeAsString(), |
| 431 attachment_metadata.record(0).id().SerializeAsString()); | 418 attachment_metadata.record(0).id().SerializeAsString()); |
| 432 ASSERT_TRUE(attachment_metadata.record(0).is_on_server()); | 419 ASSERT_TRUE(attachment_metadata.record(0).is_on_server()); |
| 433 | 420 |
| 434 // See that attachment_metadata and server_attachment_metadata are equal. | 421 // See that attachment_metadata and server_attachment_metadata are equal. |
| (...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 528 } | 515 } |
| 529 | 516 |
| 530 void ApplyPasswordUpdates(sessions::StatusController* status) { | 517 void ApplyPasswordUpdates(sessions::StatusController* status) { |
| 531 update_handler_map_.find(PASSWORDS)->second->ApplyUpdates(status); | 518 update_handler_map_.find(PASSWORDS)->second->ApplyUpdates(status); |
| 532 } | 519 } |
| 533 | 520 |
| 534 void ApplyArticlesUpdates(sessions::StatusController* status) { | 521 void ApplyArticlesUpdates(sessions::StatusController* status) { |
| 535 update_handler_map_.find(ARTICLES)->second->ApplyUpdates(status); | 522 update_handler_map_.find(ARTICLES)->second->ApplyUpdates(status); |
| 536 } | 523 } |
| 537 | 524 |
| 538 TestEntryFactory* entry_factory() { | 525 TestEntryFactory* entry_factory() { return entry_factory_.get(); } |
| 539 return entry_factory_.get(); | |
| 540 } | |
| 541 | 526 |
| 542 syncable::Directory* directory() { | 527 syncable::Directory* directory() { return dir_maker_.directory(); } |
| 543 return dir_maker_.directory(); | |
| 544 } | |
| 545 | 528 |
| 546 private: | 529 private: |
| 547 base::MessageLoop loop_; // Needed to initialize the directory. | 530 base::MessageLoop loop_; // Needed to initialize the directory. |
| 548 TestDirectorySetterUpper dir_maker_; | 531 TestDirectorySetterUpper dir_maker_; |
| 549 std::unique_ptr<TestEntryFactory> entry_factory_; | 532 std::unique_ptr<TestEntryFactory> entry_factory_; |
| 550 | 533 |
| 551 scoped_refptr<FakeModelWorker> ui_worker_; | 534 scoped_refptr<FakeModelWorker> ui_worker_; |
| 552 scoped_refptr<FakeModelWorker> password_worker_; | 535 scoped_refptr<FakeModelWorker> password_worker_; |
| 553 scoped_refptr<FakeModelWorker> passive_worker_; | 536 scoped_refptr<FakeModelWorker> passive_worker_; |
| 554 | 537 |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 600 ASSERT_TRUE(child.good()); | 583 ASSERT_TRUE(child.good()); |
| 601 | 584 |
| 602 EXPECT_FALSE(parent.GetIsUnsynced()); | 585 EXPECT_FALSE(parent.GetIsUnsynced()); |
| 603 EXPECT_FALSE(parent.GetIsUnappliedUpdate()); | 586 EXPECT_FALSE(parent.GetIsUnappliedUpdate()); |
| 604 EXPECT_FALSE(child.GetIsUnsynced()); | 587 EXPECT_FALSE(child.GetIsUnsynced()); |
| 605 EXPECT_FALSE(child.GetIsUnappliedUpdate()); | 588 EXPECT_FALSE(child.GetIsUnappliedUpdate()); |
| 606 } | 589 } |
| 607 } | 590 } |
| 608 | 591 |
| 609 // Test that the applicator can handle updates delivered out of order. | 592 // Test that the applicator can handle updates delivered out of order. |
| 610 TEST_F(DirectoryUpdateHandlerApplyUpdateTest, | 593 TEST_F(DirectoryUpdateHandlerApplyUpdateTest, BookmarkChildrenBeforeParent) { |
| 611 BookmarkChildrenBeforeParent) { | |
| 612 // Start with some bookmarks whose parents are unknown. | 594 // Start with some bookmarks whose parents are unknown. |
| 613 std::string root_server_id = Id::GetRoot().GetServerId(); | 595 std::string root_server_id = Id::GetRoot().GetServerId(); |
| 614 int64_t a_handle = entry_factory()->CreateUnappliedNewBookmarkItemWithParent( | 596 int64_t a_handle = entry_factory()->CreateUnappliedNewBookmarkItemWithParent( |
| 615 "a_child_created_first", DefaultBookmarkSpecifics(), "parent"); | 597 "a_child_created_first", DefaultBookmarkSpecifics(), "parent"); |
| 616 int64_t x_handle = entry_factory()->CreateUnappliedNewBookmarkItemWithParent( | 598 int64_t x_handle = entry_factory()->CreateUnappliedNewBookmarkItemWithParent( |
| 617 "x_child_created_first", DefaultBookmarkSpecifics(), "parent"); | 599 "x_child_created_first", DefaultBookmarkSpecifics(), "parent"); |
| 618 | 600 |
| 619 // Update application will fail. | 601 // Update application will fail. |
| 620 sessions::StatusController status1; | 602 sessions::StatusController status1; |
| 621 ApplyBookmarkUpdates(&status1); | 603 ApplyBookmarkUpdates(&status1); |
| (...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 748 syncable::MutableEntry entry(&trans, syncable::GET_BY_HANDLE, handle); | 730 syncable::MutableEntry entry(&trans, syncable::GET_BY_HANDLE, handle); |
| 749 ASSERT_TRUE(entry.good()); | 731 ASSERT_TRUE(entry.good()); |
| 750 | 732 |
| 751 // Re-parent from root to "Y" | 733 // Re-parent from root to "Y" |
| 752 entry.PutServerVersion(entry_factory()->GetNextRevision()); | 734 entry.PutServerVersion(entry_factory()->GetNextRevision()); |
| 753 entry.PutIsUnappliedUpdate(true); | 735 entry.PutIsUnappliedUpdate(true); |
| 754 entry.PutServerParentId(TestIdFactory::MakeServer("Y")); | 736 entry.PutServerParentId(TestIdFactory::MakeServer("Y")); |
| 755 } | 737 } |
| 756 | 738 |
| 757 // Item 'Y' is child of 'X'. | 739 // Item 'Y' is child of 'X'. |
| 758 entry_factory()->CreateUnsyncedItem( | 740 entry_factory()->CreateUnsyncedItem(TestIdFactory::MakeServer("Y"), |
| 759 TestIdFactory::MakeServer("Y"), TestIdFactory::MakeServer("X"), "Y", true, | 741 TestIdFactory::MakeServer("X"), "Y", true, |
| 760 BOOKMARKS, NULL); | 742 BOOKMARKS, NULL); |
| 761 | 743 |
| 762 // If the server's update were applied, we would have X be a child of Y, and Y | 744 // If the server's update were applied, we would have X be a child of Y, and Y |
| 763 // as a child of X. That's a directory loop. The UpdateApplicator should | 745 // as a child of X. That's a directory loop. The UpdateApplicator should |
| 764 // prevent the update from being applied and note that this is a hierarchy | 746 // prevent the update from being applied and note that this is a hierarchy |
| 765 // conflict. | 747 // conflict. |
| 766 | 748 |
| 767 sessions::StatusController status; | 749 sessions::StatusController status; |
| 768 ApplyBookmarkUpdates(&status); | 750 ApplyBookmarkUpdates(&status); |
| 769 | 751 |
| 770 // This should count as a hierarchy conflict. | 752 // This should count as a hierarchy conflict. |
| 771 const UpdateCounters& counters = GetBookmarksUpdateCounters(); | 753 const UpdateCounters& counters = GetBookmarksUpdateCounters(); |
| 772 EXPECT_EQ(1, counters.num_hierarchy_conflict_application_failures); | 754 EXPECT_EQ(1, counters.num_hierarchy_conflict_application_failures); |
| 773 | 755 |
| 774 { | 756 { |
| 775 syncable::ReadTransaction trans(FROM_HERE, directory()); | 757 syncable::ReadTransaction trans(FROM_HERE, directory()); |
| 776 syncable::Entry e(&trans, syncable::GET_BY_HANDLE, handle); | 758 syncable::Entry e(&trans, syncable::GET_BY_HANDLE, handle); |
| 777 ASSERT_TRUE(e.good()); | 759 ASSERT_TRUE(e.good()); |
| 778 EXPECT_TRUE(e.GetIsUnappliedUpdate()); | 760 EXPECT_TRUE(e.GetIsUnappliedUpdate()); |
| 779 EXPECT_FALSE(e.GetIsUnsynced()); | 761 EXPECT_FALSE(e.GetIsUnsynced()); |
| 780 } | 762 } |
| 781 } | 763 } |
| 782 | 764 |
| 783 // Test update application where the update has been orphaned by a local folder | 765 // Test update application where the update has been orphaned by a local folder |
| 784 // deletion. The update application attempt should fail. | 766 // deletion. The update application attempt should fail. |
| 785 TEST_F(DirectoryUpdateHandlerApplyUpdateTest, | 767 TEST_F(DirectoryUpdateHandlerApplyUpdateTest, HierarchyConflictDeletedParent) { |
| 786 HierarchyConflictDeletedParent) { | |
| 787 // Create a locally deleted parent item. | 768 // Create a locally deleted parent item. |
| 788 int64_t parent_handle; | 769 int64_t parent_handle; |
| 789 entry_factory()->CreateUnsyncedItem( | 770 entry_factory()->CreateUnsyncedItem(Id::CreateFromServerId("parent"), |
| 790 Id::CreateFromServerId("parent"), TestIdFactory::root(), | 771 TestIdFactory::root(), "parent", true, |
| 791 "parent", true, BOOKMARKS, &parent_handle); | 772 BOOKMARKS, &parent_handle); |
| 792 { | 773 { |
| 793 syncable::WriteTransaction trans(FROM_HERE, UNITTEST, directory()); | 774 syncable::WriteTransaction trans(FROM_HERE, UNITTEST, directory()); |
| 794 syncable::MutableEntry entry(&trans, | 775 syncable::MutableEntry entry(&trans, syncable::GET_BY_HANDLE, |
| 795 syncable::GET_BY_HANDLE, | |
| 796 parent_handle); | 776 parent_handle); |
| 797 entry.PutIsDel(true); | 777 entry.PutIsDel(true); |
| 798 } | 778 } |
| 799 | 779 |
| 800 // Create an incoming child from the server. | 780 // Create an incoming child from the server. |
| 801 int64_t child_handle = entry_factory()->CreateUnappliedNewItemWithParent( | 781 int64_t child_handle = entry_factory()->CreateUnappliedNewItemWithParent( |
| 802 "child", DefaultBookmarkSpecifics(), "parent"); | 782 "child", DefaultBookmarkSpecifics(), "parent"); |
| 803 | 783 |
| 804 // The server's update may seem valid to some other client, but on this client | 784 // The server's update may seem valid to some other client, but on this client |
| 805 // that new item's parent no longer exists. The update should not be applied | 785 // that new item's parent no longer exists. The update should not be applied |
| (...skipping 15 matching lines...) Expand all Loading... |
| 821 | 801 |
| 822 // Attempt to apply an update that deletes a folder where the folder has | 802 // Attempt to apply an update that deletes a folder where the folder has |
| 823 // locally-created children. The update application should fail. | 803 // locally-created children. The update application should fail. |
| 824 TEST_F(DirectoryUpdateHandlerApplyUpdateTest, | 804 TEST_F(DirectoryUpdateHandlerApplyUpdateTest, |
| 825 HierarchyConflictDeleteNonEmptyDirectory) { | 805 HierarchyConflictDeleteNonEmptyDirectory) { |
| 826 // Create a server-deleted folder as a child of root node. | 806 // Create a server-deleted folder as a child of root node. |
| 827 int64_t parent_handle = | 807 int64_t parent_handle = |
| 828 entry_factory()->CreateSyncedItem("parent", BOOKMARKS, true); | 808 entry_factory()->CreateSyncedItem("parent", BOOKMARKS, true); |
| 829 { | 809 { |
| 830 syncable::WriteTransaction trans(FROM_HERE, UNITTEST, directory()); | 810 syncable::WriteTransaction trans(FROM_HERE, UNITTEST, directory()); |
| 831 syncable::MutableEntry entry(&trans, | 811 syncable::MutableEntry entry(&trans, syncable::GET_BY_HANDLE, |
| 832 syncable::GET_BY_HANDLE, | |
| 833 parent_handle); | 812 parent_handle); |
| 834 ASSERT_TRUE(entry.good()); | 813 ASSERT_TRUE(entry.good()); |
| 835 | 814 |
| 836 // Delete it on the server. | 815 // Delete it on the server. |
| 837 entry.PutServerVersion(entry_factory()->GetNextRevision()); | 816 entry.PutServerVersion(entry_factory()->GetNextRevision()); |
| 838 entry.PutIsUnappliedUpdate(true); | 817 entry.PutIsUnappliedUpdate(true); |
| 839 entry.PutServerParentId(TestIdFactory::root()); | 818 entry.PutServerParentId(TestIdFactory::root()); |
| 840 entry.PutServerIsDel(true); | 819 entry.PutServerIsDel(true); |
| 841 } | 820 } |
| 842 | 821 |
| 843 // Create a local child of the server-deleted directory. | 822 // Create a local child of the server-deleted directory. |
| 844 entry_factory()->CreateUnsyncedItem( | 823 entry_factory()->CreateUnsyncedItem(TestIdFactory::MakeServer("child"), |
| 845 TestIdFactory::MakeServer("child"), TestIdFactory::MakeServer("parent"), | 824 TestIdFactory::MakeServer("parent"), |
| 846 "child", false, BOOKMARKS, NULL); | 825 "child", false, BOOKMARKS, NULL); |
| 847 | 826 |
| 848 // The server's request to delete the directory must be ignored, otherwise our | 827 // The server's request to delete the directory must be ignored, otherwise our |
| 849 // unsynced new child would be orphaned. This is a hierarchy conflict. | 828 // unsynced new child would be orphaned. This is a hierarchy conflict. |
| 850 | 829 |
| 851 sessions::StatusController status; | 830 sessions::StatusController status; |
| 852 ApplyBookmarkUpdates(&status); | 831 ApplyBookmarkUpdates(&status); |
| 853 | 832 |
| 854 // This should count as a hierarchy conflict. | 833 // This should count as a hierarchy conflict. |
| 855 const UpdateCounters& counters = GetBookmarksUpdateCounters(); | 834 const UpdateCounters& counters = GetBookmarksUpdateCounters(); |
| 856 EXPECT_EQ(1, counters.num_hierarchy_conflict_application_failures); | 835 EXPECT_EQ(1, counters.num_hierarchy_conflict_application_failures); |
| 857 | 836 |
| 858 { | 837 { |
| 859 syncable::ReadTransaction trans(FROM_HERE, directory()); | 838 syncable::ReadTransaction trans(FROM_HERE, directory()); |
| 860 syncable::Entry parent(&trans, syncable::GET_BY_HANDLE, parent_handle); | 839 syncable::Entry parent(&trans, syncable::GET_BY_HANDLE, parent_handle); |
| 861 ASSERT_TRUE(parent.good()); | 840 ASSERT_TRUE(parent.good()); |
| 862 EXPECT_TRUE(parent.GetIsUnappliedUpdate()); | 841 EXPECT_TRUE(parent.GetIsUnappliedUpdate()); |
| 863 EXPECT_FALSE(parent.GetIsUnsynced()); | 842 EXPECT_FALSE(parent.GetIsUnsynced()); |
| 864 } | 843 } |
| 865 } | 844 } |
| 866 | 845 |
| 867 // Attempt to apply updates where the updated item's parent is not known to this | 846 // Attempt to apply updates where the updated item's parent is not known to this |
| 868 // client. The update application attempt should fail. | 847 // client. The update application attempt should fail. |
| 869 TEST_F(DirectoryUpdateHandlerApplyUpdateTest, | 848 TEST_F(DirectoryUpdateHandlerApplyUpdateTest, HierarchyConflictUnknownParent) { |
| 870 HierarchyConflictUnknownParent) { | |
| 871 // We shouldn't be able to do anything with either of these items. | 849 // We shouldn't be able to do anything with either of these items. |
| 872 int64_t x_handle = entry_factory()->CreateUnappliedNewItemWithParent( | 850 int64_t x_handle = entry_factory()->CreateUnappliedNewItemWithParent( |
| 873 "some_item", DefaultBookmarkSpecifics(), "unknown_parent"); | 851 "some_item", DefaultBookmarkSpecifics(), "unknown_parent"); |
| 874 int64_t y_handle = entry_factory()->CreateUnappliedNewItemWithParent( | 852 int64_t y_handle = entry_factory()->CreateUnappliedNewItemWithParent( |
| 875 "some_other_item", DefaultBookmarkSpecifics(), "some_item"); | 853 "some_other_item", DefaultBookmarkSpecifics(), "some_item"); |
| 876 | 854 |
| 877 sessions::StatusController status; | 855 sessions::StatusController status; |
| 878 ApplyBookmarkUpdates(&status); | 856 ApplyBookmarkUpdates(&status); |
| 879 | 857 |
| 880 const UpdateCounters& counters = GetBookmarksUpdateCounters(); | 858 const UpdateCounters& counters = GetBookmarksUpdateCounters(); |
| (...skipping 163 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1044 sync_pb::PasswordSpecificsData data; | 1022 sync_pb::PasswordSpecificsData data; |
| 1045 data.set_origin("http://example.com/1"); | 1023 data.set_origin("http://example.com/1"); |
| 1046 { | 1024 { |
| 1047 syncable::ReadTransaction trans(FROM_HERE, directory()); | 1025 syncable::ReadTransaction trans(FROM_HERE, directory()); |
| 1048 cryptographer = directory()->GetCryptographer(&trans); | 1026 cryptographer = directory()->GetCryptographer(&trans); |
| 1049 | 1027 |
| 1050 KeyParams params = {"localhost", "dummy", "foobar"}; | 1028 KeyParams params = {"localhost", "dummy", "foobar"}; |
| 1051 cryptographer->AddKey(params); | 1029 cryptographer->AddKey(params); |
| 1052 | 1030 |
| 1053 cryptographer->Encrypt(data, | 1031 cryptographer->Encrypt(data, |
| 1054 specifics.mutable_password()->mutable_encrypted()); | 1032 specifics.mutable_password()->mutable_encrypted()); |
| 1055 } | 1033 } |
| 1056 decryptable_handle = | 1034 decryptable_handle = |
| 1057 entry_factory()->CreateUnappliedNewItem("item1", specifics, false); | 1035 entry_factory()->CreateUnappliedNewItem("item1", specifics, false); |
| 1058 } | 1036 } |
| 1059 { | 1037 { |
| 1060 // Create a new cryptographer, independent of the one in the session. | 1038 // Create a new cryptographer, independent of the one in the session. |
| 1061 Cryptographer other_cryptographer(cryptographer->encryptor()); | 1039 Cryptographer other_cryptographer(cryptographer->encryptor()); |
| 1062 KeyParams params = {"localhost", "dummy", "bazqux"}; | 1040 KeyParams params = {"localhost", "dummy", "bazqux"}; |
| 1063 other_cryptographer.AddKey(params); | 1041 other_cryptographer.AddKey(params); |
| 1064 | 1042 |
| 1065 sync_pb::EntitySpecifics specifics; | 1043 sync_pb::EntitySpecifics specifics; |
| 1066 sync_pb::PasswordSpecificsData data; | 1044 sync_pb::PasswordSpecificsData data; |
| 1067 data.set_origin("http://example.com/2"); | 1045 data.set_origin("http://example.com/2"); |
| 1068 | 1046 |
| 1069 other_cryptographer.Encrypt(data, | 1047 other_cryptographer.Encrypt( |
| 1070 specifics.mutable_password()->mutable_encrypted()); | 1048 data, specifics.mutable_password()->mutable_encrypted()); |
| 1071 undecryptable_handle = | 1049 undecryptable_handle = |
| 1072 entry_factory()->CreateUnappliedNewItem("item2", specifics, false); | 1050 entry_factory()->CreateUnappliedNewItem("item2", specifics, false); |
| 1073 } | 1051 } |
| 1074 | 1052 |
| 1075 sessions::StatusController status; | 1053 sessions::StatusController status; |
| 1076 ApplyPasswordUpdates(&status); | 1054 ApplyPasswordUpdates(&status); |
| 1077 | 1055 |
| 1078 const UpdateCounters& counters = GetPasswordsUpdateCounters(); | 1056 const UpdateCounters& counters = GetPasswordsUpdateCounters(); |
| 1079 EXPECT_EQ(1, counters.num_encryption_conflict_application_failures) | 1057 EXPECT_EQ(1, counters.num_encryption_conflict_application_failures) |
| 1080 << "The updates that can't be decrypted should be in encryption " | 1058 << "The updates that can't be decrypted should be in encryption " |
| (...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1178 const UpdateCounters& counters = GetArticlesUpdateCounters(); | 1156 const UpdateCounters& counters = GetArticlesUpdateCounters(); |
| 1179 EXPECT_EQ(1, counters.num_updates_applied); | 1157 EXPECT_EQ(1, counters.num_updates_applied); |
| 1180 EXPECT_EQ(1, counters.num_local_overwrites); | 1158 EXPECT_EQ(1, counters.num_local_overwrites); |
| 1181 EXPECT_EQ(0, counters.num_server_overwrites); | 1159 EXPECT_EQ(0, counters.num_server_overwrites); |
| 1182 local_metadata = entry_factory()->GetLocalAttachmentMetadataForItem(handle); | 1160 local_metadata = entry_factory()->GetLocalAttachmentMetadataForItem(handle); |
| 1183 EXPECT_EQ(server_metadata.SerializeAsString(), | 1161 EXPECT_EQ(server_metadata.SerializeAsString(), |
| 1184 local_metadata.SerializeAsString()); | 1162 local_metadata.SerializeAsString()); |
| 1185 } | 1163 } |
| 1186 | 1164 |
| 1187 } // namespace syncer | 1165 } // namespace syncer |
| OLD | NEW |