OLD | NEW |
---|---|
1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 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 "components/sync_driver/device_info_service.h" | 5 #include "components/sync_driver/device_info_service.h" |
6 | 6 |
7 #include <map> | 7 #include <map> |
8 #include <set> | 8 #include <set> |
9 #include <string> | 9 #include <string> |
10 #include <utility> | 10 #include <utility> |
11 | 11 |
12 #include "base/bind.h" | 12 #include "base/bind.h" |
13 #include "base/memory/scoped_ptr.h" | 13 #include "base/memory/scoped_ptr.h" |
14 #include "base/message_loop/message_loop.h" | 14 #include "base/message_loop/message_loop.h" |
15 #include "base/run_loop.h" | 15 #include "base/run_loop.h" |
16 #include "base/strings/stringprintf.h" | 16 #include "base/strings/stringprintf.h" |
17 #include "components/sync_driver/local_device_info_provider_mock.h" | 17 #include "components/sync_driver/local_device_info_provider_mock.h" |
18 #include "sync/api/data_batch.h" | 18 #include "sync/api/data_batch.h" |
19 #include "sync/api/entity_data.h" | |
19 #include "sync/api/metadata_batch.h" | 20 #include "sync/api/metadata_batch.h" |
20 #include "sync/api/model_type_store.h" | 21 #include "sync/api/model_type_store.h" |
21 #include "sync/internal_api/public/test/model_type_store_test_util.h" | 22 #include "sync/internal_api/public/test/model_type_store_test_util.h" |
22 #include "sync/protocol/data_type_state.pb.h" | 23 #include "sync/protocol/data_type_state.pb.h" |
23 #include "testing/gtest/include/gtest/gtest.h" | 24 #include "testing/gtest/include/gtest/gtest.h" |
24 | 25 |
25 namespace sync_driver_v2 { | 26 namespace sync_driver_v2 { |
26 | 27 |
27 using syncer::SyncError; | 28 using syncer::SyncError; |
28 using syncer_v2::DataBatch; | 29 using syncer_v2::DataBatch; |
29 using syncer_v2::EntityChange; | 30 using syncer_v2::EntityChange; |
30 using syncer_v2::EntityChangeList; | 31 using syncer_v2::EntityChangeList; |
31 using syncer_v2::EntityData; | 32 using syncer_v2::EntityData; |
33 using syncer_v2::EntityDataList; | |
32 using syncer_v2::EntityDataPtr; | 34 using syncer_v2::EntityDataPtr; |
33 using syncer_v2::MetadataBatch; | 35 using syncer_v2::MetadataBatch; |
34 using syncer_v2::MetadataChangeList; | 36 using syncer_v2::MetadataChangeList; |
35 using syncer_v2::ModelTypeChangeProcessor; | 37 using syncer_v2::ModelTypeChangeProcessor; |
36 using syncer_v2::ModelTypeService; | 38 using syncer_v2::ModelTypeService; |
37 using syncer_v2::ModelTypeStore; | 39 using syncer_v2::ModelTypeStore; |
38 using syncer_v2::ModelTypeStoreTestUtil; | 40 using syncer_v2::ModelTypeStoreTestUtil; |
39 using syncer_v2::TagAndData; | 41 using syncer_v2::TagAndData; |
40 using sync_driver::DeviceInfo; | 42 using sync_driver::DeviceInfo; |
41 using sync_driver::DeviceInfoTracker; | 43 using sync_driver::DeviceInfoTracker; |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
91 expected.find(pair.first); | 93 expected.find(pair.first); |
92 ASSERT_NE(iter, expected.end()); | 94 ASSERT_NE(iter, expected.end()); |
93 AssertEqual(iter->second, pair.second->specifics.device_info()); | 95 AssertEqual(iter->second, pair.second->specifics.device_info()); |
94 // Removing allows us to verify we don't see the same item multiple times, | 96 // Removing allows us to verify we don't see the same item multiple times, |
95 // and that we saw everything we expected. | 97 // and that we saw everything we expected. |
96 expected.erase(iter); | 98 expected.erase(iter); |
97 } | 99 } |
98 ASSERT_TRUE(expected.empty()); | 100 ASSERT_TRUE(expected.empty()); |
99 } | 101 } |
100 | 102 |
103 // Creats an EntityData/EntityDataPtr around a copy of the given specifics. | |
104 EntityDataPtr SpecificsToEntity(const DeviceInfoSpecifics& specifics) { | |
105 EntityData data; | |
106 // These tests do not care about the tag hash, but EntityData and friends | |
107 // cannot differentiate between the default EntityData object if the hash | |
108 // is unset, which causes pass/copy operations to no-op and things start to | |
109 // break, so we throw in a junk value and forget about it. | |
110 data.client_tag_hash = "junk"; | |
111 *data.specifics.mutable_device_info() = specifics; | |
112 return data.PassToPtr(); | |
113 } | |
114 | |
101 // Instead of actually processing anything, simply accumulates all instructions | 115 // Instead of actually processing anything, simply accumulates all instructions |
102 // in members that can then be accessed. TODO(skym): If this ends up being | 116 // in members that can then be accessed. TODO(skym): If this ends up being |
103 // useful for other model type unittests it should be moved out to a shared | 117 // useful for other model type unittests it should be moved out to a shared |
104 // location. | 118 // location. |
105 class FakeModelTypeChangeProcessor : public ModelTypeChangeProcessor { | 119 class FakeModelTypeChangeProcessor : public ModelTypeChangeProcessor { |
106 public: | 120 public: |
107 FakeModelTypeChangeProcessor() {} | 121 FakeModelTypeChangeProcessor() {} |
108 ~FakeModelTypeChangeProcessor() override {} | 122 ~FakeModelTypeChangeProcessor() override {} |
109 | 123 |
110 void Put(const std::string& client_tag, | 124 void Put(const std::string& client_tag, |
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
201 specifics.set_sync_user_agent( | 215 specifics.set_sync_user_agent( |
202 base::StringPrintf("sync user agent %d", label)); | 216 base::StringPrintf("sync user agent %d", label)); |
203 specifics.set_chrome_version( | 217 specifics.set_chrome_version( |
204 base::StringPrintf("chrome version %d", label)); | 218 base::StringPrintf("chrome version %d", label)); |
205 specifics.set_backup_timestamp(label); | 219 specifics.set_backup_timestamp(label); |
206 specifics.set_signin_scoped_device_id( | 220 specifics.set_signin_scoped_device_id( |
207 base::StringPrintf("signin scoped device id %d", label)); | 221 base::StringPrintf("signin scoped device id %d", label)); |
208 return specifics; | 222 return specifics; |
209 } | 223 } |
210 | 224 |
225 // Override to allow specific cache guids. | |
226 DeviceInfoSpecifics GenerateTestSpecifics(const std::string& guid) { | |
227 DeviceInfoSpecifics specifics(GenerateTestSpecifics()); | |
228 specifics.set_cache_guid(guid); | |
229 return specifics; | |
230 } | |
231 | |
211 // Helper method to reduce duplicated code between tests. Wraps the given | 232 // Helper method to reduce duplicated code between tests. Wraps the given |
212 // specifics object in an EntityData and EntityChange of type ACTION_ADD, and | 233 // specifics object in an EntityData and EntityChange of type ACTION_ADD, and |
213 // pushes them onto the given change list. The corresponding client tag the | 234 // pushes them onto the given change list. The corresponding client tag the |
214 // service determines is returned. Instance method because we need access to | 235 // service determines is returned. Instance method because we need access to |
215 // service to generate the tag. | 236 // service to generate the tag. |
216 std::string PushBackEntityChangeAdd(const DeviceInfoSpecifics& specifics, | 237 std::string PushBackEntityChangeAdd(const DeviceInfoSpecifics& specifics, |
217 EntityChangeList* changes) { | 238 EntityChangeList* changes) { |
218 EntityData data; | 239 EntityDataPtr ptr = SpecificsToEntity(specifics); |
219 // These tests do not care about the tag hash, but EntityData and friends | 240 const std::string tag = service()->GetClientTag(ptr.value()); |
220 // cannot differentiate between the default EntityData object if the hash | 241 changes->push_back(EntityChange::CreateAdd(tag, ptr)); |
221 // is unset, which causes pass/copy operations to no-op and things start to | |
222 // break, so we throw in a junk value and forget about it. | |
223 data.client_tag_hash = "junk"; | |
224 *data.specifics.mutable_device_info() = specifics; | |
225 const std::string tag = service()->GetClientTag(data); | |
226 changes->push_back(EntityChange::CreateAdd(tag, data.PassToPtr())); | |
227 return tag; | 242 return tag; |
228 } | 243 } |
229 | 244 |
230 // Allows access to the store before that will ultimately be used to | 245 // Allows access to the store before that will ultimately be used to |
231 // initialize the service. | 246 // initialize the service. |
232 ModelTypeStore* store() { | 247 ModelTypeStore* store() { |
233 EXPECT_TRUE(store_); | 248 EXPECT_TRUE(store_); |
234 return store_.get(); | 249 return store_.get(); |
235 } | 250 } |
236 | 251 |
(...skipping 293 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
530 // ASSERT_EQ(state.encryption_key_name(), | 545 // ASSERT_EQ(state.encryption_key_name(), |
531 // processor()->metadata()->GetDataTypeState().encryption_key_name()); | 546 // processor()->metadata()->GetDataTypeState().encryption_key_name()); |
532 } | 547 } |
533 | 548 |
534 TEST_F(DeviceInfoServiceTest, ApplySyncChangesWithLocalGuid) { | 549 TEST_F(DeviceInfoServiceTest, ApplySyncChangesWithLocalGuid) { |
535 InitializeAndPump(); | 550 InitializeAndPump(); |
536 | 551 |
537 // The point of this test is to try to apply remote changes that have the same | 552 // The point of this test is to try to apply remote changes that have the same |
538 // cache guid as the local device. The service should ignore these changes | 553 // cache guid as the local device. The service should ignore these changes |
539 // since only it should be performing writes on its data. | 554 // since only it should be performing writes on its data. |
540 DeviceInfoSpecifics specifics = GenerateTestSpecifics(); | 555 DeviceInfoSpecifics specifics = |
541 specifics.set_cache_guid(local_device()->GetLocalDeviceInfo()->guid()); | 556 GenerateTestSpecifics(local_device()->GetLocalDeviceInfo()->guid()); |
542 | 557 |
543 EntityChangeList data_changes; | 558 EntityChangeList data_changes; |
544 const std::string tag = PushBackEntityChangeAdd(specifics, &data_changes); | 559 const std::string tag = PushBackEntityChangeAdd(specifics, &data_changes); |
545 const SyncError error = service()->ApplySyncChanges( | 560 const SyncError error = service()->ApplySyncChanges( |
546 service()->CreateMetadataChangeList(), data_changes); | 561 service()->CreateMetadataChangeList(), data_changes); |
547 | 562 |
548 ASSERT_FALSE(error.IsSet()); | 563 ASSERT_FALSE(error.IsSet()); |
549 ASSERT_FALSE(service()->GetDeviceInfo(tag)); | 564 ASSERT_FALSE(service()->GetDeviceInfo(tag)); |
550 } | 565 } |
551 | 566 |
552 TEST_F(DeviceInfoServiceTest, ApplyDeleteNonexistent) { | 567 TEST_F(DeviceInfoServiceTest, ApplyDeleteNonexistent) { |
553 InitializeAndPump(); | 568 InitializeAndPump(); |
554 EntityChangeList delete_changes; | 569 EntityChangeList delete_changes; |
555 delete_changes.push_back(EntityChange::CreateDelete("tag")); | 570 delete_changes.push_back(EntityChange::CreateDelete("tag")); |
556 const SyncError error = service()->ApplySyncChanges( | 571 const SyncError error = service()->ApplySyncChanges( |
557 service()->CreateMetadataChangeList(), delete_changes); | 572 service()->CreateMetadataChangeList(), delete_changes); |
558 ASSERT_FALSE(error.IsSet()); | 573 ASSERT_FALSE(error.IsSet()); |
559 } | 574 } |
560 | 575 |
576 TEST_F(DeviceInfoServiceTest, MergeBeforeInit) { | |
577 InitializeService(); | |
578 const SyncError error = service()->MergeSyncData( | |
579 service()->CreateMetadataChangeList(), EntityDataList()); | |
580 ASSERT_TRUE(error.IsSet()); | |
581 } | |
582 | |
583 TEST_F(DeviceInfoServiceTest, MergeEmpty) { | |
584 InitializeAndPump(); | |
585 SetProcessorAndPump(); | |
586 const SyncError error = service()->MergeSyncData( | |
587 service()->CreateMetadataChangeList(), EntityDataList()); | |
588 ASSERT_FALSE(error.IsSet()); | |
589 } | |
590 | |
591 TEST_F(DeviceInfoServiceTest, MergeWithData) { | |
592 const DeviceInfoSpecifics unique_local(GenerateTestSpecifics("unique_local")); | |
593 const DeviceInfoSpecifics conflict_local(GenerateTestSpecifics("conflict")); | |
594 DeviceInfoSpecifics conflict_remote(GenerateTestSpecifics("conflict")); | |
595 DeviceInfoSpecifics unique_remote(GenerateTestSpecifics("unique_remote")); | |
596 | |
597 scoped_ptr<WriteBatch> batch = store()->CreateWriteBatch(); | |
598 store()->WriteData(batch.get(), unique_local.cache_guid(), | |
599 unique_local.SerializeAsString()); | |
600 store()->WriteData(batch.get(), conflict_local.cache_guid(), | |
601 conflict_local.SerializeAsString()); | |
602 store()->CommitWriteBatch(std::move(batch), | |
603 base::Bind(&AssertResultIsSuccess)); | |
604 | |
605 InitializeAndPump(); | |
606 SetProcessorAndPump(); | |
607 | |
608 EntityDataList remote_input; | |
609 remote_input.push_back(SpecificsToEntity(conflict_remote)); | |
610 remote_input.push_back(SpecificsToEntity(unique_remote)); | |
611 | |
612 DataTypeState state; | |
613 state.set_encryption_key_name("ekn"); | |
614 scoped_ptr<MetadataChangeList> metadata_changes( | |
615 service()->CreateMetadataChangeList()); | |
616 metadata_changes->UpdateDataTypeState(state); | |
617 | |
maxbogue
2016/02/23 01:04:02
Add a TODO here to actually commit |metadata_chang
skym
2016/03/04 20:28:10
Whoopps, it should be getting passed into MergeSyn
| |
618 const SyncError error = service()->MergeSyncData( | |
619 service()->CreateMetadataChangeList(), remote_input); | |
620 ASSERT_FALSE(error.IsSet()); | |
621 | |
622 // The remote should beat the local in conflict. | |
623 ASSERT_EQ(3u, service()->GetAllDeviceInfo().size()); | |
624 AssertEqual(unique_local, *service()->GetDeviceInfo("unique_local").get()); | |
625 AssertEqual(unique_remote, *service()->GetDeviceInfo("unique_remote").get()); | |
626 AssertEqual(conflict_remote, *service()->GetDeviceInfo("conflict").get()); | |
627 | |
628 // Service should have told the processor about the existance of unique_local. | |
629 ASSERT_TRUE(processor()->delete_set().empty()); | |
630 ASSERT_EQ(1u, processor()->put_map().size()); | |
631 auto it = processor()->put_map().find("unique_local"); | |
632 ASSERT_NE(processor()->put_map().end(), it); | |
633 AssertEqual(unique_local, it->second->specifics.device_info()); | |
634 | |
635 // TODO(skym): Uncomment once SimpleMetadataChangeList::TransferChanges is | |
636 // implemented. | |
637 // ASSERT_EQ(state.encryption_key_name(), | |
638 // processor()->metadata()->GetDataTypeState().encryption_key_name()); | |
639 } | |
640 | |
641 TEST_F(DeviceInfoServiceTest, MergeLocalGuid) { | |
642 InitializeAndPump(); | |
643 SetProcessorAndPump(); | |
644 | |
645 // Service should ignore this because it uses the local device's guid. | |
646 DeviceInfoSpecifics specifics( | |
647 GenerateTestSpecifics(local_device()->GetLocalDeviceInfo()->guid())); | |
648 EntityDataList remote_input; | |
649 remote_input.push_back(SpecificsToEntity(specifics)); | |
650 | |
651 const SyncError error = service()->MergeSyncData( | |
652 service()->CreateMetadataChangeList(), remote_input); | |
653 ASSERT_FALSE(error.IsSet()); | |
654 ASSERT_TRUE(service()->GetAllDeviceInfo().empty()); | |
655 ASSERT_TRUE(processor()->delete_set().empty()); | |
656 ASSERT_TRUE(processor()->put_map().empty()); | |
657 } | |
658 | |
561 } // namespace | 659 } // namespace |
562 | 660 |
563 } // namespace sync_driver_v2 | 661 } // namespace sync_driver_v2 |
OLD | NEW |