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 |