| OLD | NEW |
| (Empty) |
| 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 | |
| 3 // found in the LICENSE file. | |
| 4 | |
| 5 #include "components/sync/api/fake_model_type_service.h" | |
| 6 | |
| 7 #include <utility> | |
| 8 | |
| 9 #include "base/bind.h" | |
| 10 #include "base/memory/ptr_util.h" | |
| 11 #include "components/sync/core/data_batch_impl.h" | |
| 12 #include "components/sync/core/simple_metadata_change_list.h" | |
| 13 #include "components/sync/syncable/syncable_util.h" | |
| 14 #include "testing/gtest/include/gtest/gtest.h" | |
| 15 | |
| 16 using sync_pb::EntitySpecifics; | |
| 17 using sync_pb::EntityMetadata; | |
| 18 using sync_pb::ModelTypeState; | |
| 19 | |
| 20 namespace syncer { | |
| 21 | |
| 22 namespace { | |
| 23 | |
| 24 // It is intentionally very difficult to copy an EntityData, as in normal code | |
| 25 // we never want to. However, since we store the data as an EntityData for the | |
| 26 // test code here, this function is needed to manually copy it. | |
| 27 std::unique_ptr<EntityData> CopyEntityData(const EntityData& old_data) { | |
| 28 std::unique_ptr<EntityData> new_data(new EntityData()); | |
| 29 new_data->id = old_data.id; | |
| 30 new_data->client_tag_hash = old_data.client_tag_hash; | |
| 31 new_data->non_unique_name = old_data.non_unique_name; | |
| 32 new_data->specifics = old_data.specifics; | |
| 33 new_data->creation_time = old_data.creation_time; | |
| 34 new_data->modification_time = old_data.modification_time; | |
| 35 return new_data; | |
| 36 } | |
| 37 | |
| 38 } // namespace | |
| 39 | |
| 40 // static | |
| 41 std::string FakeModelTypeService::ClientTagFromKey(const std::string& key) { | |
| 42 return "ClientTag_" + key; | |
| 43 } | |
| 44 | |
| 45 // static | |
| 46 std::string FakeModelTypeService::TagHashFromKey(const std::string& key) { | |
| 47 return syncable::GenerateSyncableHash( | |
| 48 PREFERENCES, FakeModelTypeService::ClientTagFromKey(key)); | |
| 49 } | |
| 50 | |
| 51 // static | |
| 52 EntitySpecifics FakeModelTypeService::GenerateSpecifics( | |
| 53 const std::string& key, | |
| 54 const std::string& value) { | |
| 55 EntitySpecifics specifics; | |
| 56 specifics.mutable_preference()->set_name(key); | |
| 57 specifics.mutable_preference()->set_value(value); | |
| 58 return specifics; | |
| 59 } | |
| 60 | |
| 61 // static | |
| 62 std::unique_ptr<EntityData> FakeModelTypeService::GenerateEntityData( | |
| 63 const std::string& key, | |
| 64 const std::string& value) { | |
| 65 std::unique_ptr<EntityData> entity_data = base::MakeUnique<EntityData>(); | |
| 66 entity_data->client_tag_hash = TagHashFromKey(key); | |
| 67 entity_data->specifics = GenerateSpecifics(key, value); | |
| 68 entity_data->non_unique_name = key; | |
| 69 return entity_data; | |
| 70 } | |
| 71 | |
| 72 FakeModelTypeService::Store::Store() {} | |
| 73 FakeModelTypeService::Store::~Store() {} | |
| 74 | |
| 75 void FakeModelTypeService::Store::PutData(const std::string& key, | |
| 76 const EntityData& data) { | |
| 77 data_change_count_++; | |
| 78 data_store_[key] = CopyEntityData(data); | |
| 79 } | |
| 80 | |
| 81 void FakeModelTypeService::Store::PutMetadata(const std::string& key, | |
| 82 const EntityMetadata& metadata) { | |
| 83 metadata_change_count_++; | |
| 84 metadata_store_[key] = metadata; | |
| 85 } | |
| 86 | |
| 87 void FakeModelTypeService::Store::RemoveData(const std::string& key) { | |
| 88 data_change_count_++; | |
| 89 data_store_.erase(key); | |
| 90 } | |
| 91 | |
| 92 void FakeModelTypeService::Store::RemoveMetadata(const std::string& key) { | |
| 93 metadata_change_count_++; | |
| 94 metadata_store_.erase(key); | |
| 95 } | |
| 96 | |
| 97 bool FakeModelTypeService::Store::HasData(const std::string& key) const { | |
| 98 return data_store_.find(key) != data_store_.end(); | |
| 99 } | |
| 100 | |
| 101 bool FakeModelTypeService::Store::HasMetadata(const std::string& key) const { | |
| 102 return metadata_store_.find(key) != metadata_store_.end(); | |
| 103 } | |
| 104 | |
| 105 const EntityData& FakeModelTypeService::Store::GetData( | |
| 106 const std::string& key) const { | |
| 107 return *data_store_.find(key)->second; | |
| 108 } | |
| 109 | |
| 110 const std::string& FakeModelTypeService::Store::GetValue( | |
| 111 const std::string& key) const { | |
| 112 return GetData(key).specifics.preference().value(); | |
| 113 } | |
| 114 | |
| 115 const sync_pb::EntityMetadata& FakeModelTypeService::Store::GetMetadata( | |
| 116 const std::string& key) const { | |
| 117 return metadata_store_.find(key)->second; | |
| 118 } | |
| 119 | |
| 120 std::unique_ptr<MetadataBatch> | |
| 121 FakeModelTypeService::Store::CreateMetadataBatch() const { | |
| 122 std::unique_ptr<MetadataBatch> metadata_batch(new MetadataBatch()); | |
| 123 metadata_batch->SetModelTypeState(model_type_state_); | |
| 124 for (const auto& kv : metadata_store_) { | |
| 125 metadata_batch->AddMetadata(kv.first, kv.second); | |
| 126 } | |
| 127 return metadata_batch; | |
| 128 } | |
| 129 | |
| 130 void FakeModelTypeService::Store::Reset() { | |
| 131 data_change_count_ = 0; | |
| 132 metadata_change_count_ = 0; | |
| 133 data_store_.clear(); | |
| 134 metadata_store_.clear(); | |
| 135 model_type_state_.Clear(); | |
| 136 } | |
| 137 | |
| 138 FakeModelTypeService::FakeModelTypeService( | |
| 139 const ChangeProcessorFactory& change_processor_factory) | |
| 140 : ModelTypeService(change_processor_factory, PREFERENCES) {} | |
| 141 | |
| 142 FakeModelTypeService::~FakeModelTypeService() { | |
| 143 CheckPostConditions(); | |
| 144 } | |
| 145 | |
| 146 EntitySpecifics FakeModelTypeService::WriteItem(const std::string& key, | |
| 147 const std::string& value) { | |
| 148 std::unique_ptr<EntityData> entity_data = GenerateEntityData(key, value); | |
| 149 EntitySpecifics specifics_copy = entity_data->specifics; | |
| 150 WriteItem(key, std::move(entity_data)); | |
| 151 return specifics_copy; | |
| 152 } | |
| 153 | |
| 154 // Overloaded form to allow passing of custom entity data. | |
| 155 void FakeModelTypeService::WriteItem(const std::string& key, | |
| 156 std::unique_ptr<EntityData> entity_data) { | |
| 157 db_.PutData(key, *entity_data); | |
| 158 if (change_processor()) { | |
| 159 std::unique_ptr<MetadataChangeList> change_list( | |
| 160 new SimpleMetadataChangeList()); | |
| 161 change_processor()->Put(key, std::move(entity_data), change_list.get()); | |
| 162 ApplyMetadataChangeList(std::move(change_list)); | |
| 163 } | |
| 164 } | |
| 165 | |
| 166 void FakeModelTypeService::DeleteItem(const std::string& key) { | |
| 167 db_.RemoveData(key); | |
| 168 if (change_processor()) { | |
| 169 std::unique_ptr<MetadataChangeList> change_list( | |
| 170 new SimpleMetadataChangeList()); | |
| 171 change_processor()->Delete(key, change_list.get()); | |
| 172 ApplyMetadataChangeList(std::move(change_list)); | |
| 173 } | |
| 174 } | |
| 175 | |
| 176 std::unique_ptr<MetadataChangeList> | |
| 177 FakeModelTypeService::CreateMetadataChangeList() { | |
| 178 return std::unique_ptr<MetadataChangeList>(new SimpleMetadataChangeList()); | |
| 179 } | |
| 180 | |
| 181 SyncError FakeModelTypeService::MergeSyncData( | |
| 182 std::unique_ptr<MetadataChangeList> metadata_changes, | |
| 183 EntityDataMap data_map) { | |
| 184 if (service_error_.IsSet()) { | |
| 185 SyncError error = service_error_; | |
| 186 service_error_ = SyncError(); | |
| 187 return error; | |
| 188 } | |
| 189 // Commit any local entities that aren't being overwritten by the server. | |
| 190 for (const auto& kv : db_.all_data()) { | |
| 191 if (data_map.find(kv.first) == data_map.end()) { | |
| 192 change_processor()->Put(kv.first, CopyEntityData(*kv.second), | |
| 193 metadata_changes.get()); | |
| 194 } | |
| 195 } | |
| 196 // Store any new remote entities. | |
| 197 for (const auto& kv : data_map) { | |
| 198 db_.PutData(kv.first, kv.second.value()); | |
| 199 } | |
| 200 ApplyMetadataChangeList(std::move(metadata_changes)); | |
| 201 return SyncError(); | |
| 202 } | |
| 203 | |
| 204 SyncError FakeModelTypeService::ApplySyncChanges( | |
| 205 std::unique_ptr<MetadataChangeList> metadata_changes, | |
| 206 EntityChangeList entity_changes) { | |
| 207 if (service_error_.IsSet()) { | |
| 208 SyncError error = service_error_; | |
| 209 service_error_ = SyncError(); | |
| 210 return error; | |
| 211 } | |
| 212 for (const EntityChange& change : entity_changes) { | |
| 213 switch (change.type()) { | |
| 214 case EntityChange::ACTION_ADD: | |
| 215 EXPECT_FALSE(db_.HasData(change.storage_key())); | |
| 216 db_.PutData(change.storage_key(), change.data()); | |
| 217 break; | |
| 218 case EntityChange::ACTION_UPDATE: | |
| 219 EXPECT_TRUE(db_.HasData(change.storage_key())); | |
| 220 db_.PutData(change.storage_key(), change.data()); | |
| 221 break; | |
| 222 case EntityChange::ACTION_DELETE: | |
| 223 EXPECT_TRUE(db_.HasData(change.storage_key())); | |
| 224 db_.RemoveData(change.storage_key()); | |
| 225 break; | |
| 226 } | |
| 227 } | |
| 228 ApplyMetadataChangeList(std::move(metadata_changes)); | |
| 229 return SyncError(); | |
| 230 } | |
| 231 | |
| 232 void FakeModelTypeService::ApplyMetadataChangeList( | |
| 233 std::unique_ptr<MetadataChangeList> change_list) { | |
| 234 DCHECK(change_list); | |
| 235 SimpleMetadataChangeList* changes = | |
| 236 static_cast<SimpleMetadataChangeList*>(change_list.get()); | |
| 237 const auto& metadata_changes = changes->GetMetadataChanges(); | |
| 238 for (const auto& kv : metadata_changes) { | |
| 239 switch (kv.second.type) { | |
| 240 case SimpleMetadataChangeList::UPDATE: | |
| 241 db_.PutMetadata(kv.first, kv.second.metadata); | |
| 242 break; | |
| 243 case SimpleMetadataChangeList::CLEAR: | |
| 244 EXPECT_TRUE(db_.HasMetadata(kv.first)); | |
| 245 db_.RemoveMetadata(kv.first); | |
| 246 break; | |
| 247 } | |
| 248 } | |
| 249 if (changes->HasModelTypeStateChange()) { | |
| 250 const SimpleMetadataChangeList::ModelTypeStateChange& state_change = | |
| 251 changes->GetModelTypeStateChange(); | |
| 252 switch (state_change.type) { | |
| 253 case SimpleMetadataChangeList::UPDATE: | |
| 254 db_.set_model_type_state(state_change.state); | |
| 255 break; | |
| 256 case SimpleMetadataChangeList::CLEAR: | |
| 257 db_.set_model_type_state(ModelTypeState()); | |
| 258 break; | |
| 259 } | |
| 260 } | |
| 261 } | |
| 262 | |
| 263 void FakeModelTypeService::GetData(StorageKeyList keys, DataCallback callback) { | |
| 264 if (service_error_.IsSet()) { | |
| 265 callback.Run(service_error_, nullptr); | |
| 266 service_error_ = SyncError(); | |
| 267 return; | |
| 268 } | |
| 269 std::unique_ptr<DataBatchImpl> batch(new DataBatchImpl()); | |
| 270 for (const std::string& key : keys) { | |
| 271 DCHECK(db_.HasData(key)) << "No data for " << key; | |
| 272 batch->Put(key, CopyEntityData(db_.GetData(key))); | |
| 273 } | |
| 274 callback.Run(SyncError(), std::move(batch)); | |
| 275 } | |
| 276 | |
| 277 void FakeModelTypeService::GetAllData(DataCallback callback) { | |
| 278 if (service_error_.IsSet()) { | |
| 279 callback.Run(service_error_, nullptr); | |
| 280 service_error_ = SyncError(); | |
| 281 return; | |
| 282 } | |
| 283 std::unique_ptr<DataBatchImpl> batch(new DataBatchImpl()); | |
| 284 for (const auto& kv : db_.all_data()) { | |
| 285 batch->Put(kv.first, CopyEntityData(*kv.second)); | |
| 286 } | |
| 287 callback.Run(SyncError(), std::move(batch)); | |
| 288 } | |
| 289 | |
| 290 std::string FakeModelTypeService::GetClientTag(const EntityData& entity_data) { | |
| 291 return ClientTagFromKey(entity_data.specifics.preference().name()); | |
| 292 } | |
| 293 | |
| 294 std::string FakeModelTypeService::GetStorageKey(const EntityData& entity_data) { | |
| 295 return entity_data.specifics.preference().name(); | |
| 296 } | |
| 297 | |
| 298 void FakeModelTypeService::OnChangeProcessorSet() {} | |
| 299 | |
| 300 void FakeModelTypeService::SetServiceError(SyncError::ErrorType error_type) { | |
| 301 DCHECK(!service_error_.IsSet()); | |
| 302 service_error_ = SyncError(FROM_HERE, error_type, "TestError", PREFERENCES); | |
| 303 } | |
| 304 | |
| 305 ConflictResolution FakeModelTypeService::ResolveConflict( | |
| 306 const EntityData& local_data, | |
| 307 const EntityData& remote_data) const { | |
| 308 DCHECK(conflict_resolution_); | |
| 309 return std::move(*conflict_resolution_); | |
| 310 } | |
| 311 | |
| 312 void FakeModelTypeService::SetConflictResolution( | |
| 313 ConflictResolution resolution) { | |
| 314 conflict_resolution_.reset(new ConflictResolution(std::move(resolution))); | |
| 315 } | |
| 316 | |
| 317 void FakeModelTypeService::CheckPostConditions() { | |
| 318 DCHECK(!service_error_.IsSet()); | |
| 319 } | |
| 320 | |
| 321 } // namespace syncer | |
| OLD | NEW |