Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(71)

Side by Side Diff: sync/test/fake_server/fake_server.cc

Issue 267723012: Use FakeServer-based invalidations for Sync tests (try #2) (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 6 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 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 "sync/test/fake_server/fake_server.h" 5 #include "sync/test/fake_server/fake_server.h"
6 6
7 #include <algorithm>
7 #include <limits> 8 #include <limits>
8 #include <string> 9 #include <string>
9 #include <vector> 10 #include <vector>
10 11
11 #include "base/basictypes.h" 12 #include "base/basictypes.h"
12 #include "base/guid.h" 13 #include "base/guid.h"
13 #include "base/logging.h" 14 #include "base/logging.h"
14 #include "base/memory/scoped_ptr.h" 15 #include "base/memory/scoped_ptr.h"
15 #include "base/stl_util.h" 16 #include "base/stl_util.h"
16 #include "base/strings/string_number_conversions.h" 17 #include "base/strings/string_number_conversions.h"
17 #include "base/strings/string_util.h" 18 #include "base/strings/string_util.h"
18 #include "base/strings/stringprintf.h" 19 #include "base/strings/stringprintf.h"
19 #include "base/synchronization/lock.h" 20 #include "base/synchronization/lock.h"
20 #include "net/base/net_errors.h" 21 #include "net/base/net_errors.h"
21 #include "net/http/http_status_code.h" 22 #include "net/http/http_status_code.h"
22 #include "sync/internal_api/public/base/model_type.h" 23 #include "sync/internal_api/public/base/model_type.h"
23 #include "sync/protocol/sync.pb.h" 24 #include "sync/protocol/sync.pb.h"
24 #include "sync/test/fake_server/bookmark_entity.h" 25 #include "sync/test/fake_server/bookmark_entity.h"
25 #include "sync/test/fake_server/permanent_entity.h" 26 #include "sync/test/fake_server/permanent_entity.h"
26 #include "sync/test/fake_server/tombstone_entity.h" 27 #include "sync/test/fake_server/tombstone_entity.h"
27 #include "sync/test/fake_server/unique_client_entity.h" 28 #include "sync/test/fake_server/unique_client_entity.h"
28 29
29 using std::string; 30 using std::string;
30 using std::vector; 31 using std::vector;
31 32
32 using base::AutoLock;
33 using syncer::GetModelType; 33 using syncer::GetModelType;
34 using syncer::ModelType; 34 using syncer::ModelType;
35 using syncer::ModelTypeSet; 35 using syncer::ModelTypeSet;
36 36
37 // The default birthday value. 37 // The default birthday value.
38 static const char kDefaultBirthday[] = "1234567890"; 38 static const char kDefaultBirthday[] = "1234567890";
39 39
40 // The default keystore key. 40 // The default keystore key.
41 static const char kDefaultKeystoreKey[] = "1111111111111111"; 41 static const char kDefaultKeystoreKey[] = "1111111111111111";
42 42
(...skipping 188 matching lines...) Expand 10 before | Expand all | Expand 10 after
231 SaveEntity(mobile_bookmarks_entity); 231 SaveEntity(mobile_bookmarks_entity);
232 return true; 232 return true;
233 } 233 }
234 234
235 void FakeServer::SaveEntity(FakeServerEntity* entity) { 235 void FakeServer::SaveEntity(FakeServerEntity* entity) {
236 delete entities_[entity->GetId()]; 236 delete entities_[entity->GetId()];
237 entity->SetVersion(++version_); 237 entity->SetVersion(++version_);
238 entities_[entity->GetId()] = entity; 238 entities_[entity->GetId()] = entity;
239 } 239 }
240 240
241 int FakeServer::HandleCommand(const string& request, 241 void FakeServer::HandleCommand(const string& request,
242 int* response_code, 242 const HandleCommandCallback& callback) {
243 string* response) {
244 AutoLock lock(lock_);
245
246 sync_pb::ClientToServerMessage message; 243 sync_pb::ClientToServerMessage message;
247 bool parsed = message.ParseFromString(request); 244 bool parsed = message.ParseFromString(request);
248 DCHECK(parsed); 245 DCHECK(parsed);
249 246
250 sync_pb::ClientToServerResponse response_proto; 247 sync_pb::ClientToServerResponse response_proto;
251 bool success; 248 bool success;
252 switch (message.message_contents()) { 249 switch (message.message_contents()) {
253 case sync_pb::ClientToServerMessage::GET_UPDATES: 250 case sync_pb::ClientToServerMessage::GET_UPDATES:
254 success = HandleGetUpdatesRequest(message.get_updates(), 251 success = HandleGetUpdatesRequest(message.get_updates(),
255 response_proto.mutable_get_updates()); 252 response_proto.mutable_get_updates());
256 break; 253 break;
257 case sync_pb::ClientToServerMessage::COMMIT: 254 case sync_pb::ClientToServerMessage::COMMIT:
258 success = HandleCommitRequest(message.commit(), 255 success = HandleCommitRequest(message.commit(),
259 response_proto.mutable_commit()); 256 response_proto.mutable_commit());
260 break; 257 break;
261 default: 258 default:
262 return net::ERR_NOT_IMPLEMENTED; 259 callback.Run(net::ERR_NOT_IMPLEMENTED, 0, string());;
260 return;
263 } 261 }
264 262
265 if (!success) { 263 if (!success) {
266 // TODO(pvalenzuela): Add logging here so that tests have more info about 264 // TODO(pvalenzuela): Add logging here so that tests have more info about
267 // the failure. 265 // the failure.
268 return net::HTTP_BAD_REQUEST; 266 callback.Run(net::ERR_FAILED, 0, string());
267 return;
269 } 268 }
270 269
271 response_proto.set_error_code(sync_pb::SyncEnums::SUCCESS); 270 response_proto.set_error_code(sync_pb::SyncEnums::SUCCESS);
272 response_proto.set_store_birthday(birthday_); 271 response_proto.set_store_birthday(birthday_);
273 *response_code = net::HTTP_OK; 272 callback.Run(0, net::HTTP_OK, response_proto.SerializeAsString());
274 *response = response_proto.SerializeAsString();
275 return 0;
276 } 273 }
277 274
278 bool FakeServer::HandleGetUpdatesRequest( 275 bool FakeServer::HandleGetUpdatesRequest(
279 const sync_pb::GetUpdatesMessage& get_updates, 276 const sync_pb::GetUpdatesMessage& get_updates,
280 sync_pb::GetUpdatesResponse* response) { 277 sync_pb::GetUpdatesResponse* response) {
281 // TODO(pvalenzuela): Implement batching instead of sending all information 278 // TODO(pvalenzuela): Implement batching instead of sending all information
282 // at once. 279 // at once.
283 response->set_changes_remaining(0); 280 response->set_changes_remaining(0);
284 281
285 scoped_ptr<UpdateSieve> sieve = UpdateSieve::Create(get_updates); 282 scoped_ptr<UpdateSieve> sieve = UpdateSieve::Create(get_updates);
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
317 for (vector<string>::iterator it = keystore_keys_.begin(); 314 for (vector<string>::iterator it = keystore_keys_.begin();
318 it != keystore_keys_.end(); ++it) { 315 it != keystore_keys_.end(); ++it) {
319 response->add_encryption_keys(*it); 316 response->add_encryption_keys(*it);
320 } 317 }
321 } 318 }
322 319
323 sieve->UpdateProgressMarkers(max_response_version, response); 320 sieve->UpdateProgressMarkers(max_response_version, response);
324 return true; 321 return true;
325 } 322 }
326 323
327 bool FakeServer::CommitEntity( 324 string FakeServer::CommitEntity(
328 const sync_pb::SyncEntity& client_entity, 325 const sync_pb::SyncEntity& client_entity,
329 sync_pb::CommitResponse_EntryResponse* entry_response, 326 sync_pb::CommitResponse_EntryResponse* entry_response,
330 string client_guid, 327 string client_guid,
331 std::map<string, string>* client_to_server_ids) { 328 string parent_id) {
332 if (client_entity.version() == 0 && client_entity.deleted()) { 329 if (client_entity.version() == 0 && client_entity.deleted()) {
333 return false; 330 return string();
334 } 331 }
335 332
336 FakeServerEntity* entity; 333 FakeServerEntity* entity;
337 if (client_entity.deleted()) { 334 if (client_entity.deleted()) {
338 entity = TombstoneEntity::Create(client_entity.id_string()); 335 entity = TombstoneEntity::Create(client_entity.id_string());
339 // TODO(pvalenzuela): Change the behavior of DeleteChilden so that it does 336 // TODO(pvalenzuela): Change the behavior of DeleteChilden so that it does
340 // not modify server data if it fails. 337 // not modify server data if it fails.
341 if (!DeleteChildren(client_entity.id_string())) { 338 if (!DeleteChildren(client_entity.id_string())) {
342 return false; 339 return string();
343 } 340 }
344 } else if (GetModelType(client_entity) == syncer::NIGORI) { 341 } else if (GetModelType(client_entity) == syncer::NIGORI) {
345 // NIGORI is the only permanent item type that should be updated by the 342 // NIGORI is the only permanent item type that should be updated by the
346 // client. 343 // client.
347 entity = PermanentEntity::CreateUpdatedNigoriEntity( 344 entity = PermanentEntity::CreateUpdatedNigoriEntity(
348 client_entity, 345 client_entity,
349 entities_[client_entity.id_string()]); 346 entities_[client_entity.id_string()]);
350 } else if (client_entity.has_client_defined_unique_tag()) { 347 } else if (client_entity.has_client_defined_unique_tag()) {
351 if (entities_.find(client_entity.id_string()) != entities_.end()) { 348 if (entities_.find(client_entity.id_string()) != entities_.end()) {
352 entity = UniqueClientEntity::CreateUpdatedVersion( 349 entity = UniqueClientEntity::CreateUpdatedVersion(
353 client_entity, 350 client_entity,
354 entities_[client_entity.id_string()]); 351 entities_[client_entity.id_string()]);
355 } else { 352 } else {
356 entity = UniqueClientEntity::CreateNew(client_entity); 353 entity = UniqueClientEntity::CreateNew(client_entity);
357 } 354 }
358 } else { 355 } else {
359 string parent_id = client_entity.parent_id_string();
360 if (client_to_server_ids->find(parent_id) !=
361 client_to_server_ids->end()) {
362 parent_id = (*client_to_server_ids)[parent_id];
363 }
364 // TODO(pvalenzuela): Validate entity's parent ID. 356 // TODO(pvalenzuela): Validate entity's parent ID.
365 if (entities_.find(client_entity.id_string()) != entities_.end()) { 357 if (entities_.find(client_entity.id_string()) != entities_.end()) {
366 entity = BookmarkEntity::CreateUpdatedVersion( 358 entity = BookmarkEntity::CreateUpdatedVersion(
367 client_entity, 359 client_entity,
368 entities_[client_entity.id_string()], 360 entities_[client_entity.id_string()],
369 parent_id); 361 parent_id);
370 } else { 362 } else {
371 entity = BookmarkEntity::CreateNew(client_entity, parent_id, client_guid); 363 entity = BookmarkEntity::CreateNew(client_entity, parent_id, client_guid);
372 } 364 }
373 } 365 }
374 366
375 if (entity == NULL) { 367 if (entity == NULL) {
376 // TODO(pvalenzuela): Add logging so that it is easier to determine why 368 // TODO(pvalenzuela): Add logging so that it is easier to determine why
377 // creation failed. 369 // creation failed.
378 return false; 370 return string();
379 }
380
381 // Record the ID if it was renamed.
382 if (client_entity.id_string() != entity->GetId()) {
383 (*client_to_server_ids)[client_entity.id_string()] = entity->GetId();
384 } 371 }
385 372
386 SaveEntity(entity); 373 SaveEntity(entity);
387 BuildEntryResponseForSuccessfulCommit(entry_response, entity); 374 BuildEntryResponseForSuccessfulCommit(entry_response, entity);
388 return true; 375 return entity->GetId();
389 } 376 }
390 377
391 void FakeServer::BuildEntryResponseForSuccessfulCommit( 378 void FakeServer::BuildEntryResponseForSuccessfulCommit(
392 sync_pb::CommitResponse_EntryResponse* entry_response, 379 sync_pb::CommitResponse_EntryResponse* entry_response,
393 FakeServerEntity* entity) { 380 FakeServerEntity* entity) {
394 entry_response->set_response_type(sync_pb::CommitResponse::SUCCESS); 381 entry_response->set_response_type(sync_pb::CommitResponse::SUCCESS);
395 entry_response->set_id_string(entity->GetId()); 382 entry_response->set_id_string(entity->GetId());
396 383
397 if (entity->IsDeleted()) { 384 if (entity->IsDeleted()) {
398 entry_response->set_version(entity->GetVersion() + 1); 385 entry_response->set_version(entity->GetVersion() + 1);
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
435 } 422 }
436 423
437 return true; 424 return true;
438 } 425 }
439 426
440 bool FakeServer::HandleCommitRequest( 427 bool FakeServer::HandleCommitRequest(
441 const sync_pb::CommitMessage& commit, 428 const sync_pb::CommitMessage& commit,
442 sync_pb::CommitResponse* response) { 429 sync_pb::CommitResponse* response) {
443 std::map<string, string> client_to_server_ids; 430 std::map<string, string> client_to_server_ids;
444 string guid = commit.cache_guid(); 431 string guid = commit.cache_guid();
432 ModelTypeSet committed_model_types;
445 433
446 // TODO(pvalenzuela): Add validation of CommitMessage.entries. 434 // TODO(pvalenzuela): Add validation of CommitMessage.entries.
447 ::google::protobuf::RepeatedPtrField<sync_pb::SyncEntity>::const_iterator it; 435 ::google::protobuf::RepeatedPtrField<sync_pb::SyncEntity>::const_iterator it;
448 for (it = commit.entries().begin(); it != commit.entries().end(); ++it) { 436 for (it = commit.entries().begin(); it != commit.entries().end(); ++it) {
449 sync_pb::CommitResponse_EntryResponse* entry_response = 437 sync_pb::CommitResponse_EntryResponse* entry_response =
450 response->add_entryresponse(); 438 response->add_entryresponse();
451 439
452 if (!CommitEntity(*it, entry_response, guid, &client_to_server_ids)) { 440 sync_pb::SyncEntity client_entity = *it;
441 string parent_id = client_entity.parent_id_string();
442 if (client_to_server_ids.find(parent_id) !=
443 client_to_server_ids.end()) {
444 parent_id = client_to_server_ids[parent_id];
445 }
446
447 string entity_id = CommitEntity(client_entity,
448 entry_response,
449 guid,
450 parent_id);
451 if (entity_id.empty()) {
453 return false; 452 return false;
454 } 453 }
454
455 // Record the ID if it was renamed.
456 if (entity_id != client_entity.id_string()) {
457 client_to_server_ids[client_entity.id_string()] = entity_id;
458 }
459 FakeServerEntity* entity = entities_[entity_id];
460 committed_model_types.Put(entity->GetModelType());
455 } 461 }
456 462
463 FOR_EACH_OBSERVER(Observer, observers_, OnCommit(committed_model_types));
457 return true; 464 return true;
458 } 465 }
459 466
460 scoped_ptr<base::DictionaryValue> FakeServer::GetEntitiesAsDictionaryValue() { 467 scoped_ptr<base::DictionaryValue> FakeServer::GetEntitiesAsDictionaryValue() {
461 scoped_ptr<base::DictionaryValue> dictionary(new base::DictionaryValue()); 468 scoped_ptr<base::DictionaryValue> dictionary(new base::DictionaryValue());
462 469
463 // Initialize an empty ListValue for all ModelTypes. 470 // Initialize an empty ListValue for all ModelTypes.
464 ModelTypeSet all_types = ModelTypeSet::All(); 471 ModelTypeSet all_types = ModelTypeSet::All();
465 for (ModelTypeSet::Iterator it = all_types.First(); it.Good(); it.Inc()) { 472 for (ModelTypeSet::Iterator it = all_types.First(); it.Good(); it.Inc()) {
466 dictionary->Set(ModelTypeToString(it.Get()), new base::ListValue()); 473 dictionary->Set(ModelTypeToString(it.Get()), new base::ListValue());
(...skipping 15 matching lines...) Expand all
482 } 489 }
483 // TODO(pvalenzuela): Store more data for each entity so additional 490 // TODO(pvalenzuela): Store more data for each entity so additional
484 // verification can be performed. One example of additional verification 491 // verification can be performed. One example of additional verification
485 // is checking the correctness of the bookmark hierarchy. 492 // is checking the correctness of the bookmark hierarchy.
486 list_value->Append(new base::StringValue(entity->GetName())); 493 list_value->Append(new base::StringValue(entity->GetName()));
487 } 494 }
488 495
489 return dictionary.Pass(); 496 return dictionary.Pass();
490 } 497 }
491 498
499 void FakeServer::AddObserver(Observer* observer) {
500 observers_.AddObserver(observer);
501 }
502
503 void FakeServer::RemoveObserver(Observer* observer) {
504 observers_.RemoveObserver(observer);
505 }
506
492 } // namespace fake_server 507 } // namespace fake_server
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698