diff options
-rw-r--r-- | components/sync_driver/device_info_service.cc | 44 | ||||
-rw-r--r-- | components/sync_driver/device_info_service.h | 3 | ||||
-rw-r--r-- | components/sync_driver/device_info_service_unittest.cc | 100 | ||||
-rw-r--r-- | sync/api/model_type_service.h | 1 |
4 files changed, 145 insertions, 3 deletions
diff --git a/components/sync_driver/device_info_service.cc b/components/sync_driver/device_info_service.cc index 012040d..138a782 100644 --- a/components/sync_driver/device_info_service.cc +++ b/components/sync_driver/device_info_service.cc @@ -8,14 +8,17 @@ #include <vector> #include "base/bind.h" +#include "base/location.h" #include "sync/api/metadata_batch.h" #include "sync/api/sync_error.h" +#include "sync/internal_api/public/data_batch_impl.h" #include "sync/protocol/data_type_state.pb.h" #include "sync/protocol/sync.pb.h" namespace sync_driver_v2 { using syncer::SyncError; +using syncer_v2::DataBatchImpl; using syncer_v2::EntityChangeList; using syncer_v2::EntityData; using syncer_v2::EntityDataList; @@ -73,11 +76,40 @@ SyncError DeviceInfoService::ApplySyncChanges( void DeviceInfoService::GetData(ClientTagList client_tags, DataCallback callback) { - // TODO(skym): crbug.com/543405: Implementation. + if (!has_data_loaded_) { + callback.Run(SyncError(FROM_HERE, SyncError::DATATYPE_ERROR, + "Cannot call GetData before data has loaded.", + syncer::DEVICE_INFO), + scoped_ptr<DataBatchImpl>()); + return; + } + + syncer::SyncError error; + scoped_ptr<DataBatchImpl> batch(new DataBatchImpl()); + for (auto& tag : client_tags) { + auto iter = all_data_.find(tag); + if (iter != all_data_.end()) { + batch->Put(tag, CopyIntoNewEntityData(*iter->second)); + } + } + callback.Run(error, std::move(batch)); } void DeviceInfoService::GetAllData(DataCallback callback) { - // TODO(skym): crbug.com/543405: Implementation. + if (!has_data_loaded_) { + callback.Run(SyncError(FROM_HERE, SyncError::DATATYPE_ERROR, + "Cannot call GetAllData before data has loaded.", + syncer::DEVICE_INFO), + scoped_ptr<DataBatchImpl>()); + return; + } + + syncer::SyncError error; + scoped_ptr<DataBatchImpl> batch(new DataBatchImpl()); + for (auto& kv : all_data_) { + batch->Put(kv.first, CopyIntoNewEntityData(*kv.second)); + } + callback.Run(error, std::move(batch)); } std::string DeviceInfoService::GetClientTag(const EntityData& entity_data) { @@ -162,6 +194,14 @@ scoped_ptr<DeviceInfo> DeviceInfoService::CreateDeviceInfo( specifics.device_type(), specifics.signin_scoped_device_id())); } +// Static. +scoped_ptr<EntityData> DeviceInfoService::CopyIntoNewEntityData( + const DeviceInfoSpecifics& specifics) { + scoped_ptr<EntityData> entity_data(new EntityData()); + *entity_data->specifics.mutable_device_info() = specifics; + return entity_data; +} + void DeviceInfoService::StoreSpecifics( scoped_ptr<DeviceInfoSpecifics> specifics) { DVLOG(1) << "Storing DEVICE_INFO for " << specifics->client_name() diff --git a/components/sync_driver/device_info_service.h b/components/sync_driver/device_info_service.h index ec5f99e..13542a6 100644 --- a/components/sync_driver/device_info_service.h +++ b/components/sync_driver/device_info_service.h @@ -80,6 +80,9 @@ class DeviceInfoService : public syncer_v2::ModelTypeService, // Allocate new DeviceInfo from SyncData. static scoped_ptr<sync_driver::DeviceInfo> CreateDeviceInfo( const sync_pb::DeviceInfoSpecifics& specifics); + // Conversion as we prepare to hand data to the processor. + static scoped_ptr<syncer_v2::EntityData> CopyIntoNewEntityData( + const sync_pb::DeviceInfoSpecifics& specifics); // Store SyncData in the cache. void StoreSpecifics(scoped_ptr<sync_pb::DeviceInfoSpecifics> specifics); diff --git a/components/sync_driver/device_info_service_unittest.cc b/components/sync_driver/device_info_service_unittest.cc index 562f476..c9e5a4e 100644 --- a/components/sync_driver/device_info_service_unittest.cc +++ b/components/sync_driver/device_info_service_unittest.cc @@ -13,6 +13,7 @@ #include "base/message_loop/message_loop.h" #include "base/run_loop.h" #include "components/sync_driver/local_device_info_provider_mock.h" +#include "sync/api/data_batch.h" #include "sync/api/metadata_batch.h" #include "sync/api/model_type_store.h" #include "sync/internal_api/public/test/model_type_store_test_util.h" @@ -21,12 +22,15 @@ namespace sync_driver_v2 { +using syncer_v2::DataBatch; using syncer_v2::EntityData; using syncer_v2::MetadataBatch; using syncer_v2::MetadataChangeList; using syncer_v2::ModelTypeChangeProcessor; +using syncer_v2::ModelTypeService; using syncer_v2::ModelTypeStore; using syncer_v2::ModelTypeStoreTestUtil; +using syncer_v2::TagAndData; using sync_driver::DeviceInfo; using sync_driver::DeviceInfoTracker; using sync_driver::LocalDeviceInfoProviderMock; @@ -34,6 +38,7 @@ using sync_pb::DataTypeState; using sync_pb::DeviceInfoSpecifics; using sync_pb::EntitySpecifics; +using ClientTagList = ModelTypeService::ClientTagList; using Result = ModelTypeStore::Result; using WriteBatch = ModelTypeStore::WriteBatch; @@ -43,6 +48,16 @@ void AssertResultIsSuccess(Result result) { ASSERT_EQ(Result::SUCCESS, result); } +void AssertEqual(const DeviceInfoSpecifics& s1, const DeviceInfoSpecifics& s2) { + ASSERT_EQ(s1.cache_guid(), s2.cache_guid()); + ASSERT_EQ(s1.client_name(), s2.client_name()); + ASSERT_EQ(s1.device_type(), s2.device_type()); + ASSERT_EQ(s1.sync_user_agent(), s2.sync_user_agent()); + ASSERT_EQ(s1.chrome_version(), s2.chrome_version()); + ASSERT_EQ(s1.backup_timestamp(), s2.backup_timestamp()); + ASSERT_EQ(s1.signin_scoped_device_id(), s2.signin_scoped_device_id()); +} + void AssertEqual(const DeviceInfoSpecifics& specifics, const DeviceInfo& model) { ASSERT_EQ(specifics.cache_guid(), model.guid()); @@ -54,6 +69,29 @@ void AssertEqual(const DeviceInfoSpecifics& specifics, model.signin_scoped_device_id()); } +void AssertErrorFromDataBatch(syncer::SyncError error, + scoped_ptr<DataBatch> batch) { + ASSERT_TRUE(error.IsSet()); +} + +void AssertExpectedFromDataBatch( + std::map<std::string, DeviceInfoSpecifics> expected, + syncer::SyncError error, + scoped_ptr<DataBatch> batch) { + ASSERT_FALSE(error.IsSet()); + while (batch->HasNext()) { + const TagAndData& pair = batch->Next(); + std::map<std::string, DeviceInfoSpecifics>::iterator iter = + expected.find(pair.first); + ASSERT_NE(iter, expected.end()); + AssertEqual(iter->second, pair.second->specifics.device_info()); + // Removing allows us to verify we don't see the same item multiple times, + // and that we saw everything we expected. + expected.erase(iter); + } + ASSERT_TRUE(expected.empty()); +} + DeviceInfoSpecifics TestSpecifics() { DeviceInfoSpecifics specifics; specifics.set_cache_guid("a"); @@ -305,6 +343,68 @@ TEST_F(DeviceInfoServiceTest, TestInitProcBeforeStoreFinishes) { processor()->metadata()->GetDataTypeState().encryption_key_name()); } +TEST_F(DeviceInfoServiceTest, GetData) { + scoped_ptr<WriteBatch> batch = store()->CreateWriteBatch(); + DeviceInfoSpecifics specifics(TestSpecifics()); + store()->WriteData(batch.get(), "tag1", specifics.SerializeAsString()); + store()->WriteData(batch.get(), "tag2", specifics.SerializeAsString()); + store()->WriteData(batch.get(), "tag3", specifics.SerializeAsString()); + store()->CommitWriteBatch(std::move(batch), + base::Bind(&AssertResultIsSuccess)); + + InitializeAndPump(); + + std::map<std::string, DeviceInfoSpecifics> expected; + expected["tag1"] = specifics; + expected["tag3"] = specifics; + ClientTagList client_tags; + client_tags.push_back("tag1"); + client_tags.push_back("tag3"); + service()->GetData(client_tags, + base::Bind(&AssertExpectedFromDataBatch, expected)); +} + +TEST_F(DeviceInfoServiceTest, GetDataMissing) { + InitializeAndPump(); + std::map<std::string, DeviceInfoSpecifics> expected; + ClientTagList client_tags; + client_tags.push_back("tag1"); + service()->GetData(client_tags, + base::Bind(&AssertExpectedFromDataBatch, expected)); +} + +TEST_F(DeviceInfoServiceTest, GetDataNotInitialized) { + InitializeService(); + ClientTagList client_tags; + service()->GetData(client_tags, base::Bind(&AssertErrorFromDataBatch)); +} + +TEST_F(DeviceInfoServiceTest, GetAllData) { + scoped_ptr<WriteBatch> batch = store()->CreateWriteBatch(); + DeviceInfoSpecifics specifics(TestSpecifics()); + + store()->WriteData(batch.get(), "tag1", specifics.SerializeAsString()); + store()->WriteData(batch.get(), "tag2", specifics.SerializeAsString()); + store()->CommitWriteBatch(std::move(batch), + base::Bind(&AssertResultIsSuccess)); + + InitializeAndPump(); + + std::map<std::string, DeviceInfoSpecifics> expected; + expected["tag1"] = specifics; + expected["tag2"] = specifics; + ClientTagList client_tags; + client_tags.push_back("tag1"); + client_tags.push_back("tag2"); + service()->GetData(client_tags, + base::Bind(&AssertExpectedFromDataBatch, expected)); +} + +TEST_F(DeviceInfoServiceTest, GetAllDataNotInitialized) { + InitializeService(); + service()->GetAllData(base::Bind(&AssertErrorFromDataBatch)); +} + } // namespace } // namespace sync_driver_v2 diff --git a/sync/api/model_type_service.h b/sync/api/model_type_service.h index a2ec808..469ed4a 100644 --- a/sync/api/model_type_service.h +++ b/sync/api/model_type_service.h @@ -19,7 +19,6 @@ namespace syncer_v2 { class DataBatch; -class MetadataBatch; class MetadataChangeList; // Interface implemented by model types to receive updates from sync via the |