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

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

Issue 2564663003: [Sync] Fake server now updates each model type's progress markers independently. (Closed)
Patch Set: Rebase. Created 4 years 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
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 "components/sync/test/fake_server/fake_server.h" 5 #include "components/sync/test/fake_server/fake_server.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 #include <limits> 8 #include <limits>
9 #include <set> 9 #include <set>
10 #include <utility> 10 #include <utility>
11 11
12 #include "base/guid.h" 12 #include "base/guid.h"
13 #include "base/logging.h" 13 #include "base/logging.h"
14 #include "base/memory/ptr_util.h"
14 #include "base/stl_util.h" 15 #include "base/stl_util.h"
15 #include "base/strings/string_number_conversions.h" 16 #include "base/strings/string_number_conversions.h"
16 #include "base/strings/string_util.h" 17 #include "base/strings/string_util.h"
17 #include "base/strings/stringprintf.h" 18 #include "base/strings/stringprintf.h"
18 #include "base/synchronization/lock.h" 19 #include "base/synchronization/lock.h"
19 #include "components/sync/test/fake_server/bookmark_entity.h" 20 #include "components/sync/test/fake_server/bookmark_entity.h"
20 #include "components/sync/test/fake_server/permanent_entity.h" 21 #include "components/sync/test/fake_server/permanent_entity.h"
21 #include "components/sync/test/fake_server/tombstone_entity.h" 22 #include "components/sync/test/fake_server/tombstone_entity.h"
22 #include "components/sync/test/fake_server/unique_client_entity.h" 23 #include "components/sync/test/fake_server/unique_client_entity.h"
23 #include "net/base/net_errors.h" 24 #include "net/base/net_errors.h"
(...skipping 21 matching lines...) Expand all
45 46
46 // Properties of the other bookmarks permanent folder. 47 // Properties of the other bookmarks permanent folder.
47 static const char kOtherBookmarksFolderServerTag[] = "other_bookmarks"; 48 static const char kOtherBookmarksFolderServerTag[] = "other_bookmarks";
48 static const char kOtherBookmarksFolderName[] = "Other Bookmarks"; 49 static const char kOtherBookmarksFolderName[] = "Other Bookmarks";
49 50
50 // Properties of the synced bookmarks permanent folder. 51 // Properties of the synced bookmarks permanent folder.
51 static const char kSyncedBookmarksFolderServerTag[] = "synced_bookmarks"; 52 static const char kSyncedBookmarksFolderServerTag[] = "synced_bookmarks";
52 static const char kSyncedBookmarksFolderName[] = "Synced Bookmarks"; 53 static const char kSyncedBookmarksFolderName[] = "Synced Bookmarks";
53 54
54 // A filter used during GetUpdates calls to determine what information to 55 // A filter used during GetUpdates calls to determine what information to
55 // send back to the client. There is a 1:1 correspondence between any given 56 // send back to the client, filtering out old entities and tracking versions to
56 // GetUpdates call and an UpdateSieve instance. 57 // use in response progress markers. Note that only the GetUpdatesMessage's
58 // from_progress_marker is used to determine this, legacy fields are ignored.
maxbogue 2016/12/09 21:10:15 the nit of all nits: s/,/;/
skym 2016/12/09 21:51:50 Done.
57 class UpdateSieve { 59 class UpdateSieve {
58 public: 60 public:
61 explicit UpdateSieve(const sync_pb::GetUpdatesMessage& message)
62 : UpdateSieve(MessageToVersionMap(message)) {}
59 ~UpdateSieve() {} 63 ~UpdateSieve() {}
60 64
61 // Factory method for creating an UpdateSieve. 65 // Sets the progress markers in |get_updates_response| based on the highest
62 static std::unique_ptr<UpdateSieve> Create( 66 // version between request progress markers and response entities.
63 const sync_pb::GetUpdatesMessage& get_updates_message); 67 void SetProgressMarkers(
64
65 // Sets the progress markers in |get_updates_response| given the progress
66 // markers from the original GetUpdatesMessage and |new_version| (the latest
67 // version in the entries sent back).
68 void UpdateProgressMarkers(
69 int64_t new_version,
70 sync_pb::GetUpdatesResponse* get_updates_response) const { 68 sync_pb::GetUpdatesResponse* get_updates_response) const {
71 ModelTypeToVersionMap::const_iterator it; 69 for (auto& kv : response_version_map_) {
maxbogue 2016/12/09 21:10:15 const auto& perhaps?
skym 2016/12/09 21:51:50 Done.
72 for (it = request_from_version_.begin(); it != request_from_version_.end();
73 ++it) {
74 sync_pb::DataTypeProgressMarker* new_marker = 70 sync_pb::DataTypeProgressMarker* new_marker =
75 get_updates_response->add_new_progress_marker(); 71 get_updates_response->add_new_progress_marker();
76 new_marker->set_data_type_id( 72 new_marker->set_data_type_id(
77 GetSpecificsFieldNumberFromModelType(it->first)); 73 GetSpecificsFieldNumberFromModelType(kv.first));
78 74 new_marker->set_token(base::Int64ToString(kv.second));
79 int64_t version = std::max(new_version, it->second);
80 new_marker->set_token(base::Int64ToString(version));
81 } 75 }
82 } 76 }
83 77
84 // Determines whether the server should send an |entity| to the client as 78 // Determines whether the server should send an |entity| to the client as
85 // part of a GetUpdatesResponse. 79 // part of a GetUpdatesResponse. Update internal tracking of max versions as a
86 bool ClientWantsItem(const FakeServerEntity& entity) const { 80 // side effect which will later be used to set response progress markers.
81 bool ClientWantsItem(const FakeServerEntity& entity) {
87 int64_t version = entity.GetVersion(); 82 int64_t version = entity.GetVersion();
88 if (version <= min_version_) { 83 ModelType type = entity.model_type();
89 return false; 84 response_version_map_[type] =
90 } else if (entity.IsDeleted()) { 85 std::max(response_version_map_[type], version);
91 return true; 86 auto it = request_version_map_.find(type);
92 } 87 return it == request_version_map_.end() ? false : it->second < version;
93
94 ModelTypeToVersionMap::const_iterator it =
95 request_from_version_.find(entity.model_type());
96
97 return it == request_from_version_.end() ? false : it->second < version;
98 } 88 }
99 89
100 // Returns the minimum version seen across all types.
101 int64_t GetMinVersion() const { return min_version_; }
102
103 private: 90 private:
104 typedef std::map<ModelType, int64_t> ModelTypeToVersionMap; 91 typedef std::map<ModelType, int64_t> ModelTypeToVersionMap;
105 92
106 // Creates an UpdateSieve. 93 static UpdateSieve::ModelTypeToVersionMap MessageToVersionMap(
maxbogue 2016/12/09 21:10:15 you shouldn't need the UpdateSieve:: bit right?
skym 2016/12/09 21:51:50 Does not compile w/o it. I think it has to do with
107 UpdateSieve(const ModelTypeToVersionMap request_from_version, 94 const sync_pb::GetUpdatesMessage& get_updates_message) {
108 const int64_t min_version) 95 CHECK_GT(get_updates_message.from_progress_marker_size(), 0)
109 : request_from_version_(request_from_version), 96 << "A GetUpdates request must have at least one progress marker.";
110 min_version_(min_version) {} 97 ModelTypeToVersionMap request_version_map;
111 98
112 // Maps data type IDs to the latest version seen for that type. 99 for (int i = 0; i < get_updates_message.from_progress_marker_size(); i++) {
113 const ModelTypeToVersionMap request_from_version_; 100 sync_pb::DataTypeProgressMarker marker =
101 get_updates_message.from_progress_marker(i);
114 102
115 // The minimum version seen among all data types. 103 int64_t version = 0;
116 const int min_version_; 104 // Let the version remain zero if there is no token or an empty token (the
117 }; 105 // first request for this type).
106 if (marker.has_token() && !marker.token().empty()) {
107 bool parsed = base::StringToInt64(marker.token(), &version);
108 CHECK(parsed) << "Unable to parse progress marker token.";
109 }
118 110
119 std::unique_ptr<UpdateSieve> UpdateSieve::Create( 111 ModelType model_type =
120 const sync_pb::GetUpdatesMessage& get_updates_message) { 112 syncer::GetModelTypeFromSpecificsFieldNumber(marker.data_type_id());
121 CHECK_GT(get_updates_message.from_progress_marker_size(), 0) 113 request_version_map[model_type] = version;
maxbogue 2016/12/09 21:10:15 Consider adding a DCHECK above this that model_typ
skym 2016/12/09 21:51:50 Done.
122 << "A GetUpdates request must have at least one progress marker.";
123
124 UpdateSieve::ModelTypeToVersionMap request_from_version;
125 int64_t min_version = std::numeric_limits<int64_t>::max();
126 for (int i = 0; i < get_updates_message.from_progress_marker_size(); i++) {
127 sync_pb::DataTypeProgressMarker marker =
128 get_updates_message.from_progress_marker(i);
129
130 int64_t version = 0;
131 // Let the version remain zero if there is no token or an empty token (the
132 // first request for this type).
133 if (marker.has_token() && !marker.token().empty()) {
134 bool parsed = base::StringToInt64(marker.token(), &version);
135 CHECK(parsed) << "Unable to parse progress marker token.";
136 } 114 }
137 115 return request_version_map;
138 ModelType model_type =
139 syncer::GetModelTypeFromSpecificsFieldNumber(marker.data_type_id());
140 request_from_version[model_type] = version;
141
142 if (version < min_version)
143 min_version = version;
144 } 116 }
145 117
146 return std::unique_ptr<UpdateSieve>( 118 explicit UpdateSieve(const ModelTypeToVersionMap request_version_map)
147 new UpdateSieve(request_from_version, min_version)); 119 : request_version_map_(request_version_map),
148 } 120 response_version_map_(request_version_map) {}
121
122 // The largest versions the client has seen before this request, and is used
123 // to filter entities to send back to clients. The values in this map are not
124 // updated after being initially set. The presence of a type in this map is a
125 // proxy for the desire to receive results about this type.
126 const ModelTypeToVersionMap request_version_map_;
127
128 // The largest versions seen between client and server, ultimately used to
129 // send progress markers back to the client.
130 ModelTypeToVersionMap response_version_map_;
131 };
149 132
150 // Returns whether |entity| is deleted or permanent. 133 // Returns whether |entity| is deleted or permanent.
151 bool IsDeletedOrPermanent(const FakeServerEntity& entity) { 134 bool IsDeletedOrPermanent(const FakeServerEntity& entity) {
152 return entity.IsDeleted() || entity.IsPermanent(); 135 return entity.IsDeleted() || entity.IsPermanent();
153 } 136 }
154 137
155 } // namespace 138 } // namespace
156 139
157 FakeServer::FakeServer() 140 FakeServer::FakeServer()
158 : version_(0), 141 : version_(0),
(...skipping 172 matching lines...) Expand 10 before | Expand all | Expand 10 after
331 return true; 314 return true;
332 } 315 }
333 316
334 bool FakeServer::HandleGetUpdatesRequest( 317 bool FakeServer::HandleGetUpdatesRequest(
335 const sync_pb::GetUpdatesMessage& get_updates, 318 const sync_pb::GetUpdatesMessage& get_updates,
336 sync_pb::GetUpdatesResponse* response) { 319 sync_pb::GetUpdatesResponse* response) {
337 // TODO(pvalenzuela): Implement batching instead of sending all information 320 // TODO(pvalenzuela): Implement batching instead of sending all information
338 // at once. 321 // at once.
339 response->set_changes_remaining(0); 322 response->set_changes_remaining(0);
340 323
341 std::unique_ptr<UpdateSieve> sieve = UpdateSieve::Create(get_updates); 324 auto sieve = base::MakeUnique<UpdateSieve>(get_updates);
342 325
343 // This folder is called "Synced Bookmarks" by sync and is renamed 326 // This folder is called "Synced Bookmarks" by sync and is renamed
344 // "Mobile Bookmarks" by the mobile client UIs. 327 // "Mobile Bookmarks" by the mobile client UIs.
345 if (get_updates.create_mobile_bookmarks_folder() && 328 if (get_updates.create_mobile_bookmarks_folder() &&
346 !CreatePermanentBookmarkFolder(kSyncedBookmarksFolderServerTag, 329 !CreatePermanentBookmarkFolder(kSyncedBookmarksFolderServerTag,
347 kSyncedBookmarksFolderName)) { 330 kSyncedBookmarksFolderName)) {
348 return false; 331 return false;
349 } 332 }
350 333
351 bool send_encryption_keys_based_on_nigori = false; 334 bool send_encryption_keys_based_on_nigori = false;
352 int64_t max_response_version = 0;
353 for (EntityMap::const_iterator it = entities_.begin(); it != entities_.end(); 335 for (EntityMap::const_iterator it = entities_.begin(); it != entities_.end();
354 ++it) { 336 ++it) {
355 const FakeServerEntity& entity = *it->second; 337 const FakeServerEntity& entity = *it->second;
356 if (sieve->ClientWantsItem(entity)) { 338 if (sieve->ClientWantsItem(entity)) {
357 sync_pb::SyncEntity* response_entity = response->add_entries(); 339 sync_pb::SyncEntity* response_entity = response->add_entries();
358 entity.SerializeAsProto(response_entity); 340 entity.SerializeAsProto(response_entity);
359 341
360 max_response_version =
361 std::max(max_response_version, response_entity->version());
362
363 if (entity.model_type() == syncer::NIGORI) { 342 if (entity.model_type() == syncer::NIGORI) {
364 send_encryption_keys_based_on_nigori = 343 send_encryption_keys_based_on_nigori =
365 response_entity->specifics().nigori().passphrase_type() == 344 response_entity->specifics().nigori().passphrase_type() ==
366 sync_pb::NigoriSpecifics::KEYSTORE_PASSPHRASE; 345 sync_pb::NigoriSpecifics::KEYSTORE_PASSPHRASE;
367 } 346 }
368 } 347 }
369 } 348 }
370 349
371 if (send_encryption_keys_based_on_nigori || 350 if (send_encryption_keys_based_on_nigori ||
372 get_updates.need_encryption_key()) { 351 get_updates.need_encryption_key()) {
373 for (vector<string>::iterator it = keystore_keys_.begin(); 352 for (vector<string>::iterator it = keystore_keys_.begin();
374 it != keystore_keys_.end(); ++it) { 353 it != keystore_keys_.end(); ++it) {
375 response->add_encryption_keys(*it); 354 response->add_encryption_keys(*it);
376 } 355 }
377 } 356 }
378 357
379 sieve->UpdateProgressMarkers(max_response_version, response); 358 sieve->SetProgressMarkers(response);
380 return true; 359 return true;
381 } 360 }
382 361
383 string FakeServer::CommitEntity( 362 string FakeServer::CommitEntity(
384 const sync_pb::SyncEntity& client_entity, 363 const sync_pb::SyncEntity& client_entity,
385 sync_pb::CommitResponse_EntryResponse* entry_response, 364 sync_pb::CommitResponse_EntryResponse* entry_response,
386 const string& client_guid, 365 const string& client_guid,
387 const string& parent_id) { 366 const string& parent_id) {
388 if (client_entity.version() == 0 && client_entity.deleted()) { 367 if (client_entity.version() == 0 && client_entity.deleted()) {
389 return string(); 368 return string();
(...skipping 330 matching lines...) Expand 10 before | Expand all | Expand 10 after
720 DCHECK(thread_checker_.CalledOnValidThread()); 699 DCHECK(thread_checker_.CalledOnValidThread());
721 return weak_ptr_factory_.GetWeakPtr(); 700 return weak_ptr_factory_.GetWeakPtr();
722 } 701 }
723 702
724 std::string FakeServer::GetStoreBirthday() const { 703 std::string FakeServer::GetStoreBirthday() const {
725 DCHECK(thread_checker_.CalledOnValidThread()); 704 DCHECK(thread_checker_.CalledOnValidThread());
726 return base::Int64ToString(store_birthday_); 705 return base::Int64ToString(store_birthday_);
727 } 706 }
728 707
729 } // namespace fake_server 708 } // namespace fake_server
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698