| 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 <memory> | 8 #include <memory> |
| 9 #include <set> | 9 #include <set> |
| 10 #include <string> | 10 #include <string> |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 53 using sync_pb::EntitySpecifics; | 53 using sync_pb::EntitySpecifics; |
| 54 | 54 |
| 55 using ClientTagList = ModelTypeService::ClientTagList; | 55 using ClientTagList = ModelTypeService::ClientTagList; |
| 56 using RecordList = ModelTypeStore::RecordList; | 56 using RecordList = ModelTypeStore::RecordList; |
| 57 using Result = ModelTypeStore::Result; | 57 using Result = ModelTypeStore::Result; |
| 58 using StartCallback = ModelTypeChangeProcessor::StartCallback; | 58 using StartCallback = ModelTypeChangeProcessor::StartCallback; |
| 59 using WriteBatch = ModelTypeStore::WriteBatch; | 59 using WriteBatch = ModelTypeStore::WriteBatch; |
| 60 | 60 |
| 61 namespace { | 61 namespace { |
| 62 | 62 |
| 63 std::unique_ptr<DeviceInfo> CreateDeviceInfo() { |
| 64 return base::MakeUnique<DeviceInfo>( |
| 65 "guid_1", "client_1", "Chromium 10k", "Chrome 10k", |
| 66 sync_pb::SyncEnums_DeviceType_TYPE_LINUX, "device_id"); |
| 67 } |
| 68 |
| 63 void AssertResultIsSuccess(Result result) { | 69 void AssertResultIsSuccess(Result result) { |
| 64 ASSERT_EQ(Result::SUCCESS, result); | 70 ASSERT_EQ(Result::SUCCESS, result); |
| 65 } | 71 } |
| 66 | 72 |
| 67 void AssertEqual(const DeviceInfoSpecifics& s1, const DeviceInfoSpecifics& s2) { | 73 void AssertEqual(const DeviceInfoSpecifics& s1, const DeviceInfoSpecifics& s2) { |
| 68 ASSERT_EQ(s1.cache_guid(), s2.cache_guid()); | 74 ASSERT_EQ(s1.cache_guid(), s2.cache_guid()); |
| 69 ASSERT_EQ(s1.client_name(), s2.client_name()); | 75 ASSERT_EQ(s1.client_name(), s2.client_name()); |
| 70 ASSERT_EQ(s1.device_type(), s2.device_type()); | 76 ASSERT_EQ(s1.device_type(), s2.device_type()); |
| 71 ASSERT_EQ(s1.sync_user_agent(), s2.sync_user_agent()); | 77 ASSERT_EQ(s1.sync_user_agent(), s2.sync_user_agent()); |
| 72 ASSERT_EQ(s1.chrome_version(), s2.chrome_version()); | 78 ASSERT_EQ(s1.chrome_version(), s2.chrome_version()); |
| 73 ASSERT_EQ(s1.signin_scoped_device_id(), s2.signin_scoped_device_id()); | 79 ASSERT_EQ(s1.signin_scoped_device_id(), s2.signin_scoped_device_id()); |
| 74 } | 80 } |
| 75 | 81 |
| 76 void AssertEqual(const DeviceInfoSpecifics& specifics, | 82 void AssertEqual(const DeviceInfoSpecifics& specifics, |
| 77 const DeviceInfo& model) { | 83 const DeviceInfo& model) { |
| 78 ASSERT_EQ(specifics.cache_guid(), model.guid()); | 84 ASSERT_EQ(specifics.cache_guid(), model.guid()); |
| 79 ASSERT_EQ(specifics.client_name(), model.client_name()); | 85 ASSERT_EQ(specifics.client_name(), model.client_name()); |
| 80 ASSERT_EQ(specifics.device_type(), model.device_type()); | 86 ASSERT_EQ(specifics.device_type(), model.device_type()); |
| 81 ASSERT_EQ(specifics.sync_user_agent(), model.sync_user_agent()); | 87 ASSERT_EQ(specifics.sync_user_agent(), model.sync_user_agent()); |
| 82 ASSERT_EQ(specifics.chrome_version(), model.chrome_version()); | 88 ASSERT_EQ(specifics.chrome_version(), model.chrome_version()); |
| 83 ASSERT_EQ(specifics.signin_scoped_device_id(), | 89 ASSERT_EQ(specifics.signin_scoped_device_id(), |
| 84 model.signin_scoped_device_id()); | 90 model.signin_scoped_device_id()); |
| 85 } | 91 } |
| 86 | 92 |
| 87 void AssertErrorFromDataBatch(SyncError error, | |
| 88 std::unique_ptr<DataBatch> batch) { | |
| 89 ASSERT_TRUE(error.IsSet()); | |
| 90 } | |
| 91 | |
| 92 void AssertExpectedFromDataBatch( | 93 void AssertExpectedFromDataBatch( |
| 93 std::map<std::string, DeviceInfoSpecifics> expected, | 94 std::map<std::string, DeviceInfoSpecifics> expected, |
| 94 SyncError error, | 95 SyncError error, |
| 95 std::unique_ptr<DataBatch> batch) { | 96 std::unique_ptr<DataBatch> batch) { |
| 96 ASSERT_FALSE(error.IsSet()); | 97 ASSERT_FALSE(error.IsSet()); |
| 97 while (batch->HasNext()) { | 98 while (batch->HasNext()) { |
| 98 const TagAndData& pair = batch->Next(); | 99 const TagAndData& pair = batch->Next(); |
| 99 std::map<std::string, DeviceInfoSpecifics>::iterator iter = | 100 std::map<std::string, DeviceInfoSpecifics>::iterator iter = |
| 100 expected.find(pair.first); | 101 expected.find(pair.first); |
| 101 ASSERT_NE(iter, expected.end()); | 102 ASSERT_NE(iter, expected.end()); |
| 102 AssertEqual(iter->second, pair.second->specifics.device_info()); | 103 AssertEqual(iter->second, pair.second->specifics.device_info()); |
| 103 // Removing allows us to verify we don't see the same item multiple times, | 104 // Removing allows us to verify we don't see the same item multiple times, |
| 104 // and that we saw everything we expected. | 105 // and that we saw everything we expected. |
| 105 expected.erase(iter); | 106 expected.erase(iter); |
| 106 } | 107 } |
| 107 ASSERT_TRUE(expected.empty()); | 108 ASSERT_TRUE(expected.empty()); |
| 108 } | 109 } |
| 109 | 110 |
| 110 // Creats an EntityData/EntityDataPtr around a copy of the given specifics. | 111 // Creates an EntityData/EntityDataPtr around a copy of the given specifics. |
| 111 EntityDataPtr SpecificsToEntity(const DeviceInfoSpecifics& specifics) { | 112 EntityDataPtr SpecificsToEntity(const DeviceInfoSpecifics& specifics) { |
| 112 EntityData data; | 113 EntityData data; |
| 113 // These tests do not care about the tag hash, but EntityData and friends | 114 // These tests do not care about the tag hash, but EntityData and friends |
| 114 // cannot differentiate between the default EntityData object if the hash | 115 // cannot differentiate between the default EntityData object if the hash |
| 115 // is unset, which causes pass/copy operations to no-op and things start to | 116 // is unset, which causes pass/copy operations to no-op and things start to |
| 116 // break, so we throw in a junk value and forget about it. | 117 // break, so we throw in a junk value and forget about it. |
| 117 data.client_tag_hash = "junk"; | 118 data.client_tag_hash = "junk"; |
| 118 *data.specifics.mutable_device_info() = specifics; | 119 *data.specifics.mutable_device_info() = specifics; |
| 119 return data.PassToPtr(); | 120 return data.PassToPtr(); |
| 120 } | 121 } |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 162 }; | 163 }; |
| 163 | 164 |
| 164 } // namespace | 165 } // namespace |
| 165 | 166 |
| 166 class DeviceInfoServiceTest : public testing::Test, | 167 class DeviceInfoServiceTest : public testing::Test, |
| 167 public DeviceInfoTracker::Observer { | 168 public DeviceInfoTracker::Observer { |
| 168 protected: | 169 protected: |
| 169 DeviceInfoServiceTest() | 170 DeviceInfoServiceTest() |
| 170 : change_count_(0), | 171 : change_count_(0), |
| 171 store_(ModelTypeStoreTestUtil::CreateInMemoryStoreForTest()), | 172 store_(ModelTypeStoreTestUtil::CreateInMemoryStoreForTest()), |
| 172 local_device_(new LocalDeviceInfoProviderMock( | 173 local_device_(new LocalDeviceInfoProviderMock()) { |
| 173 "guid_1", | 174 local_device_->Initialize(CreateDeviceInfo()); |
| 174 "client_1", | 175 } |
| 175 "Chromium 10k", | |
| 176 "Chrome 10k", | |
| 177 sync_pb::SyncEnums_DeviceType_TYPE_LINUX, | |
| 178 "device_id")) {} | |
| 179 | 176 |
| 180 ~DeviceInfoServiceTest() override { | 177 ~DeviceInfoServiceTest() override { |
| 181 // Some tests may never initialize the service. | 178 // Some tests may never initialize the service. |
| 182 if (service_) | 179 if (service_) |
| 183 service_->RemoveObserver(this); | 180 service_->RemoveObserver(this); |
| 184 | 181 |
| 185 // Force all remaining (store) tasks to execute so we don't leak memory. | 182 // Force all remaining (store) tasks to execute so we don't leak memory. |
| 186 base::RunLoop().RunUntilIdle(); | 183 base::RunLoop().RunUntilIdle(); |
| 187 } | 184 } |
| 188 | 185 |
| (...skipping 174 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 363 base::RunLoop().RunUntilIdle(); | 360 base::RunLoop().RunUntilIdle(); |
| 364 ScopedVector<DeviceInfo> all_device_info(service()->GetAllDeviceInfo()); | 361 ScopedVector<DeviceInfo> all_device_info(service()->GetAllDeviceInfo()); |
| 365 ASSERT_EQ(1u, all_device_info.size()); | 362 ASSERT_EQ(1u, all_device_info.size()); |
| 366 ASSERT_TRUE( | 363 ASSERT_TRUE( |
| 367 local_device()->GetLocalDeviceInfo()->Equals(*all_device_info[0])); | 364 local_device()->GetLocalDeviceInfo()->Equals(*all_device_info[0])); |
| 368 } | 365 } |
| 369 | 366 |
| 370 TEST_F(DeviceInfoServiceTest, LocalProviderSubscription) { | 367 TEST_F(DeviceInfoServiceTest, LocalProviderSubscription) { |
| 371 set_local_device(base::WrapUnique(new LocalDeviceInfoProviderMock())); | 368 set_local_device(base::WrapUnique(new LocalDeviceInfoProviderMock())); |
| 372 InitializeAndPumpAndStart(); | 369 InitializeAndPumpAndStart(); |
| 370 |
| 373 ASSERT_EQ(0u, service()->GetAllDeviceInfo().size()); | 371 ASSERT_EQ(0u, service()->GetAllDeviceInfo().size()); |
| 374 local_device()->Initialize(base::WrapUnique( | 372 local_device()->Initialize(CreateDeviceInfo()); |
| 375 new DeviceInfo("guid_1", "client_1", "Chromium 10k", "Chrome 10k", | 373 base::RunLoop().RunUntilIdle(); |
| 376 sync_pb::SyncEnums_DeviceType_TYPE_LINUX, "device_id"))); | 374 |
| 377 ScopedVector<DeviceInfo> all_device_info(service()->GetAllDeviceInfo()); | 375 ScopedVector<DeviceInfo> all_device_info(service()->GetAllDeviceInfo()); |
| 378 ASSERT_EQ(1u, all_device_info.size()); | 376 ASSERT_EQ(1u, all_device_info.size()); |
| 379 ASSERT_TRUE( | 377 ASSERT_TRUE( |
| 380 local_device()->GetLocalDeviceInfo()->Equals(*all_device_info[0])); | 378 local_device()->GetLocalDeviceInfo()->Equals(*all_device_info[0])); |
| 381 } | 379 } |
| 382 | 380 |
| 381 // Metadata shouldn't be loaded before the provider is initialized. |
| 382 TEST_F(DeviceInfoServiceTest, LocalProviderInitRace) { |
| 383 set_local_device(base::WrapUnique(new LocalDeviceInfoProviderMock())); |
| 384 InitializeAndPump(); |
| 385 OnSyncStarting(); |
| 386 EXPECT_FALSE(processor()->metadata()); |
| 387 |
| 388 ASSERT_EQ(0u, service()->GetAllDeviceInfo().size()); |
| 389 local_device()->Initialize(CreateDeviceInfo()); |
| 390 base::RunLoop().RunUntilIdle(); |
| 391 |
| 392 ScopedVector<DeviceInfo> all_device_info(service()->GetAllDeviceInfo()); |
| 393 ASSERT_EQ(1u, all_device_info.size()); |
| 394 ASSERT_TRUE( |
| 395 local_device()->GetLocalDeviceInfo()->Equals(*all_device_info[0])); |
| 396 |
| 397 EXPECT_TRUE(processor()->metadata()); |
| 398 } |
| 399 |
| 383 TEST_F(DeviceInfoServiceTest, GetClientTagNormal) { | 400 TEST_F(DeviceInfoServiceTest, GetClientTagNormal) { |
| 384 InitializeService(); | 401 InitializeService(); |
| 385 const std::string guid = "abc"; | 402 const std::string guid = "abc"; |
| 386 EntitySpecifics entity_specifics; | 403 EntitySpecifics entity_specifics; |
| 387 entity_specifics.mutable_device_info()->set_cache_guid(guid); | 404 entity_specifics.mutable_device_info()->set_cache_guid(guid); |
| 388 EntityData entity_data; | 405 EntityData entity_data; |
| 389 entity_data.specifics = entity_specifics; | 406 entity_data.specifics = entity_specifics; |
| 390 EXPECT_EQ(CacheGuidToTag(guid), service()->GetClientTag(entity_data)); | 407 EXPECT_EQ(CacheGuidToTag(guid), service()->GetClientTag(entity_data)); |
| 391 } | 408 } |
| 392 | 409 |
| (...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 481 | 498 |
| 482 TEST_F(DeviceInfoServiceTest, GetDataMissing) { | 499 TEST_F(DeviceInfoServiceTest, GetDataMissing) { |
| 483 InitializeAndPump(); | 500 InitializeAndPump(); |
| 484 std::map<std::string, DeviceInfoSpecifics> expected; | 501 std::map<std::string, DeviceInfoSpecifics> expected; |
| 485 ClientTagList client_tags; | 502 ClientTagList client_tags; |
| 486 client_tags.push_back(CacheGuidToTag("tag1")); | 503 client_tags.push_back(CacheGuidToTag("tag1")); |
| 487 service()->GetData(client_tags, | 504 service()->GetData(client_tags, |
| 488 base::Bind(&AssertExpectedFromDataBatch, expected)); | 505 base::Bind(&AssertExpectedFromDataBatch, expected)); |
| 489 } | 506 } |
| 490 | 507 |
| 491 TEST_F(DeviceInfoServiceTest, GetDataNotInitialized) { | |
| 492 InitializeService(); | |
| 493 ClientTagList client_tags; | |
| 494 service()->GetData(client_tags, base::Bind(&AssertErrorFromDataBatch)); | |
| 495 } | |
| 496 | |
| 497 TEST_F(DeviceInfoServiceTest, GetAllData) { | 508 TEST_F(DeviceInfoServiceTest, GetAllData) { |
| 498 std::unique_ptr<WriteBatch> batch = store()->CreateWriteBatch(); | 509 std::unique_ptr<WriteBatch> batch = store()->CreateWriteBatch(); |
| 499 DeviceInfoSpecifics specifics1(GenerateTestSpecifics()); | 510 DeviceInfoSpecifics specifics1(GenerateTestSpecifics()); |
| 500 DeviceInfoSpecifics specifics2(GenerateTestSpecifics()); | 511 DeviceInfoSpecifics specifics2(GenerateTestSpecifics()); |
| 501 const std::string& tag1 = CacheGuidToTag(specifics1.cache_guid()); | 512 const std::string& tag1 = CacheGuidToTag(specifics1.cache_guid()); |
| 502 const std::string& tag2 = CacheGuidToTag(specifics2.cache_guid()); | 513 const std::string& tag2 = CacheGuidToTag(specifics2.cache_guid()); |
| 503 store()->WriteData(batch.get(), specifics1.cache_guid(), | 514 store()->WriteData(batch.get(), specifics1.cache_guid(), |
| 504 specifics1.SerializeAsString()); | 515 specifics1.SerializeAsString()); |
| 505 store()->WriteData(batch.get(), specifics2.cache_guid(), | 516 store()->WriteData(batch.get(), specifics2.cache_guid(), |
| 506 specifics2.SerializeAsString()); | 517 specifics2.SerializeAsString()); |
| 507 store()->CommitWriteBatch(std::move(batch), | 518 store()->CommitWriteBatch(std::move(batch), |
| 508 base::Bind(&AssertResultIsSuccess)); | 519 base::Bind(&AssertResultIsSuccess)); |
| 509 | 520 |
| 510 InitializeAndPump(); | 521 InitializeAndPump(); |
| 511 | 522 |
| 512 std::map<std::string, DeviceInfoSpecifics> expected; | 523 std::map<std::string, DeviceInfoSpecifics> expected; |
| 513 expected[tag1] = specifics1; | 524 expected[tag1] = specifics1; |
| 514 expected[tag2] = specifics2; | 525 expected[tag2] = specifics2; |
| 515 ClientTagList client_tags; | 526 ClientTagList client_tags; |
| 516 client_tags.push_back(tag1); | 527 client_tags.push_back(tag1); |
| 517 client_tags.push_back(tag2); | 528 client_tags.push_back(tag2); |
| 518 service()->GetData(client_tags, | 529 service()->GetData(client_tags, |
| 519 base::Bind(&AssertExpectedFromDataBatch, expected)); | 530 base::Bind(&AssertExpectedFromDataBatch, expected)); |
| 520 } | 531 } |
| 521 | 532 |
| 522 TEST_F(DeviceInfoServiceTest, GetAllDataNotInitialized) { | |
| 523 InitializeService(); | |
| 524 service()->GetAllData(base::Bind(&AssertErrorFromDataBatch)); | |
| 525 } | |
| 526 | |
| 527 TEST_F(DeviceInfoServiceTest, ApplySyncChangesBeforeInit) { | |
| 528 InitializeService(); | |
| 529 const SyncError error = service()->ApplySyncChanges( | |
| 530 service()->CreateMetadataChangeList(), EntityChangeList()); | |
| 531 EXPECT_TRUE(error.IsSet()); | |
| 532 EXPECT_EQ(0, change_count()); | |
| 533 } | |
| 534 | |
| 535 TEST_F(DeviceInfoServiceTest, ApplySyncChangesEmpty) { | 533 TEST_F(DeviceInfoServiceTest, ApplySyncChangesEmpty) { |
| 536 InitializeAndPump(); | 534 InitializeAndPump(); |
| 537 const SyncError error = service()->ApplySyncChanges( | 535 const SyncError error = service()->ApplySyncChanges( |
| 538 service()->CreateMetadataChangeList(), EntityChangeList()); | 536 service()->CreateMetadataChangeList(), EntityChangeList()); |
| 539 EXPECT_FALSE(error.IsSet()); | 537 EXPECT_FALSE(error.IsSet()); |
| 540 EXPECT_EQ(0, change_count()); | 538 EXPECT_EQ(0, change_count()); |
| 541 } | 539 } |
| 542 | 540 |
| 543 TEST_F(DeviceInfoServiceTest, ApplySyncChangesInMemory) { | 541 TEST_F(DeviceInfoServiceTest, ApplySyncChangesInMemory) { |
| 544 InitializeAndPump(); | 542 InitializeAndPump(); |
| (...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 639 InitializeAndPumpAndStart(); | 637 InitializeAndPumpAndStart(); |
| 640 EXPECT_EQ(1, change_count()); | 638 EXPECT_EQ(1, change_count()); |
| 641 EntityChangeList delete_changes; | 639 EntityChangeList delete_changes; |
| 642 delete_changes.push_back(EntityChange::CreateDelete(CacheGuidToTag("tag"))); | 640 delete_changes.push_back(EntityChange::CreateDelete(CacheGuidToTag("tag"))); |
| 643 const SyncError error = service()->ApplySyncChanges( | 641 const SyncError error = service()->ApplySyncChanges( |
| 644 service()->CreateMetadataChangeList(), delete_changes); | 642 service()->CreateMetadataChangeList(), delete_changes); |
| 645 EXPECT_FALSE(error.IsSet()); | 643 EXPECT_FALSE(error.IsSet()); |
| 646 EXPECT_EQ(1, change_count()); | 644 EXPECT_EQ(1, change_count()); |
| 647 } | 645 } |
| 648 | 646 |
| 649 TEST_F(DeviceInfoServiceTest, MergeWithoutProcessor) { | |
| 650 InitializeService(); | |
| 651 const SyncError error = service()->MergeSyncData( | |
| 652 service()->CreateMetadataChangeList(), EntityDataMap()); | |
| 653 EXPECT_TRUE(error.IsSet()); | |
| 654 EXPECT_EQ(0, change_count()); | |
| 655 } | |
| 656 | |
| 657 TEST_F(DeviceInfoServiceTest, MergeEmpty) { | 647 TEST_F(DeviceInfoServiceTest, MergeEmpty) { |
| 658 InitializeAndPumpAndStart(); | 648 InitializeAndPumpAndStart(); |
| 659 EXPECT_EQ(1, change_count()); | 649 EXPECT_EQ(1, change_count()); |
| 660 const SyncError error = service()->MergeSyncData( | 650 const SyncError error = service()->MergeSyncData( |
| 661 service()->CreateMetadataChangeList(), EntityDataMap()); | 651 service()->CreateMetadataChangeList(), EntityDataMap()); |
| 662 EXPECT_FALSE(error.IsSet()); | 652 EXPECT_FALSE(error.IsSet()); |
| 663 EXPECT_EQ(1, change_count()); | 653 EXPECT_EQ(1, change_count()); |
| 664 EXPECT_EQ(1u, processor()->put_map().size()); | 654 EXPECT_EQ(1u, processor()->put_map().size()); |
| 665 EXPECT_EQ(0u, processor()->delete_set().size()); | 655 EXPECT_EQ(0u, processor()->delete_set().size()); |
| 666 } | 656 } |
| (...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 777 specifics.set_cache_guid("non-local"); | 767 specifics.set_cache_guid("non-local"); |
| 778 PushBackEntityChangeAdd(specifics, &change_list); | 768 PushBackEntityChangeAdd(specifics, &change_list); |
| 779 service()->ApplySyncChanges(service()->CreateMetadataChangeList(), | 769 service()->ApplySyncChanges(service()->CreateMetadataChangeList(), |
| 780 change_list); | 770 change_list); |
| 781 EXPECT_EQ(1, service()->CountActiveDevices()); | 771 EXPECT_EQ(1, service()->CountActiveDevices()); |
| 782 } | 772 } |
| 783 | 773 |
| 784 } // namespace | 774 } // namespace |
| 785 | 775 |
| 786 } // namespace sync_driver_v2 | 776 } // namespace sync_driver_v2 |
| OLD | NEW |