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

Side by Side Diff: sync/engine/syncer_proto_util.cc

Issue 11485019: [Sync] Add tests for invalid specifics field number handling (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Rebase Created 8 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 | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 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/engine/syncer_proto_util.h" 5 #include "sync/engine/syncer_proto_util.h"
6 6
7 #include "base/format_macros.h" 7 #include "base/format_macros.h"
8 #include "base/stringprintf.h" 8 #include "base/stringprintf.h"
9 #include "google_apis/google_api_keys.h" 9 #include "google_apis/google_api_keys.h"
10 #include "sync/engine/net/server_connection_manager.h" 10 #include "sync/engine/net/server_connection_manager.h"
11 #include "sync/engine/syncer.h" 11 #include "sync/engine/syncer.h"
12 #include "sync/engine/syncer_types.h" 12 #include "sync/engine/syncer_types.h"
13 #include "sync/engine/throttled_data_type_tracker.h" 13 #include "sync/engine/throttled_data_type_tracker.h"
14 #include "sync/engine/traffic_logger.h" 14 #include "sync/engine/traffic_logger.h"
15 #include "sync/internal_api/public/base/model_type.h" 15 #include "sync/internal_api/public/base/model_type.h"
16 #include "sync/protocol/sync.pb.h"
17 #include "sync/protocol/sync_enums.pb.h" 16 #include "sync/protocol/sync_enums.pb.h"
18 #include "sync/protocol/sync_protocol_error.h" 17 #include "sync/protocol/sync_protocol_error.h"
19 #include "sync/sessions/sync_session.h" 18 #include "sync/sessions/sync_session.h"
20 #include "sync/syncable/directory.h" 19 #include "sync/syncable/directory.h"
21 #include "sync/syncable/entry.h" 20 #include "sync/syncable/entry.h"
22 #include "sync/syncable/syncable-inl.h" 21 #include "sync/syncable/syncable-inl.h"
23 #include "sync/syncable/syncable_proto_util.h" 22 #include "sync/syncable/syncable_proto_util.h"
24 #include "sync/util/time.h" 23 #include "sync/util/time.h"
25 24
26 using std::string; 25 using std::string;
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after
100 case HttpResponse::RETRY: 99 case HttpResponse::RETRY:
101 return SERVER_RETURN_TRANSIENT_ERROR; 100 return SERVER_RETURN_TRANSIENT_ERROR;
102 case HttpResponse::SERVER_CONNECTION_OK: 101 case HttpResponse::SERVER_CONNECTION_OK:
103 case HttpResponse::NONE: 102 case HttpResponse::NONE:
104 default: 103 default:
105 NOTREACHED(); 104 NOTREACHED();
106 return UNSET; 105 return UNSET;
107 } 106 }
108 } 107 }
109 108
109 SyncProtocolErrorType ConvertSyncProtocolErrorTypePBToLocalType(
110 const sync_pb::SyncEnums::ErrorType& error_type) {
111 switch (error_type) {
112 case sync_pb::SyncEnums::SUCCESS:
113 return SYNC_SUCCESS;
114 case sync_pb::SyncEnums::NOT_MY_BIRTHDAY:
115 return NOT_MY_BIRTHDAY;
116 case sync_pb::SyncEnums::THROTTLED:
117 return THROTTLED;
118 case sync_pb::SyncEnums::CLEAR_PENDING:
119 return CLEAR_PENDING;
120 case sync_pb::SyncEnums::TRANSIENT_ERROR:
121 return TRANSIENT_ERROR;
122 case sync_pb::SyncEnums::MIGRATION_DONE:
123 return MIGRATION_DONE;
124 case sync_pb::SyncEnums::UNKNOWN:
125 return UNKNOWN_ERROR;
126 case sync_pb::SyncEnums::USER_NOT_ACTIVATED:
127 case sync_pb::SyncEnums::AUTH_INVALID:
128 case sync_pb::SyncEnums::ACCESS_DENIED:
129 return INVALID_CREDENTIAL;
130 default:
131 NOTREACHED();
132 return UNKNOWN_ERROR;
133 }
134 }
135
136 ClientAction ConvertClientActionPBToLocalClientAction(
137 const sync_pb::SyncEnums::Action& action) {
138 switch (action) {
139 case sync_pb::SyncEnums::UPGRADE_CLIENT:
140 return UPGRADE_CLIENT;
141 case sync_pb::SyncEnums::CLEAR_USER_DATA_AND_RESYNC:
142 return CLEAR_USER_DATA_AND_RESYNC;
143 case sync_pb::SyncEnums::ENABLE_SYNC_ON_ACCOUNT:
144 return ENABLE_SYNC_ON_ACCOUNT;
145 case sync_pb::SyncEnums::STOP_AND_RESTART_SYNC:
146 return STOP_AND_RESTART_SYNC;
147 case sync_pb::SyncEnums::DISABLE_SYNC_ON_CLIENT:
148 return DISABLE_SYNC_ON_CLIENT;
149 case sync_pb::SyncEnums::UNKNOWN_ACTION:
150 return UNKNOWN_ACTION;
151 default:
152 NOTREACHED();
153 return UNKNOWN_ACTION;
154 }
155 }
156
110 } // namespace 157 } // namespace
111 158
112 // static 159 ModelTypeSet GetTypesToMigrate(const ClientToServerResponse& response) {
113 void SyncerProtoUtil::HandleMigrationDoneResponse(
114 const ClientToServerResponse* response,
115 sessions::SyncSession* session) {
116 LOG_IF(ERROR, 0 >= response->migrated_data_type_id_size())
117 << "MIGRATION_DONE but no types specified.";
118 ModelTypeSet to_migrate; 160 ModelTypeSet to_migrate;
119 for (int i = 0; i < response->migrated_data_type_id_size(); i++) { 161 for (int i = 0; i < response.migrated_data_type_id_size(); i++) {
120 int field_number = response->migrated_data_type_id(i); 162 int field_number = response.migrated_data_type_id(i);
121 ModelType model_type = GetModelTypeFromSpecificsFieldNumber(field_number); 163 ModelType model_type = GetModelTypeFromSpecificsFieldNumber(field_number);
122 if (!IsRealDataType(model_type)) { 164 if (!IsRealDataType(model_type)) {
123 NOTREACHED() << "Unknown field number " << field_number; 165 DLOG(WARNING) << "Unknown field number " << field_number;
124 continue; 166 continue;
125 } 167 }
126 to_migrate.Put(model_type); 168 to_migrate.Put(model_type);
127 } 169 }
128 // TODO(akalin): This should be a set union. 170 return to_migrate;
129 session->mutable_status_controller()->
130 set_types_needing_local_migration(to_migrate);
131 } 171 }
132 172
133 // static 173 SyncProtocolError ConvertErrorPBToLocalType(
134 bool SyncerProtoUtil::VerifyResponseBirthday(syncable::Directory* dir, 174 const sync_pb::ClientToServerResponse_Error& error) {
135 const ClientToServerResponse* response) { 175 SyncProtocolError sync_protocol_error;
176 sync_protocol_error.error_type = ConvertSyncProtocolErrorTypePBToLocalType(
177 error.error_type());
178 sync_protocol_error.error_description = error.error_description();
179 sync_protocol_error.url = error.url();
180 sync_protocol_error.action = ConvertClientActionPBToLocalClientAction(
181 error.action());
182
183 if (error.error_data_type_ids_size() > 0) {
184 // THROTTLED is currently the only error code that uses |error_data_types|.
185 DCHECK_EQ(error.error_type(), sync_pb::SyncEnums::THROTTLED);
186 for (int i = 0; i < error.error_data_type_ids_size(); ++i) {
187 int field_number = error.error_data_type_ids(i);
188 ModelType model_type =
189 GetModelTypeFromSpecificsFieldNumber(field_number);
190 if (!IsRealDataType(model_type)) {
191 DLOG(WARNING) << "Unknown field number " << field_number;
192 continue;
193 }
194 sync_protocol_error.error_data_types.Put(model_type);
195 }
196 }
197
198 return sync_protocol_error;
199 }
200
201 bool SyncerProtoUtil::VerifyResponseBirthday(
202 const ClientToServerResponse& response,
203 syncable::Directory* dir) {
136 204
137 std::string local_birthday = dir->store_birthday(); 205 std::string local_birthday = dir->store_birthday();
138 206
139 if (local_birthday.empty()) { 207 if (local_birthday.empty()) {
140 if (!response->has_store_birthday()) { 208 if (!response.has_store_birthday()) {
141 LOG(WARNING) << "Expected a birthday on first sync."; 209 LOG(WARNING) << "Expected a birthday on first sync.";
142 return false; 210 return false;
143 } 211 }
144 212
145 DVLOG(1) << "New store birthday: " << response->store_birthday(); 213 DVLOG(1) << "New store birthday: " << response.store_birthday();
146 dir->set_store_birthday(response->store_birthday()); 214 dir->set_store_birthday(response.store_birthday());
147 return true; 215 return true;
148 } 216 }
149 217
150 // Error situation, but we're not stuck. 218 // Error situation, but we're not stuck.
151 if (!response->has_store_birthday()) { 219 if (!response.has_store_birthday()) {
152 LOG(WARNING) << "No birthday in server response?"; 220 LOG(WARNING) << "No birthday in server response?";
153 return true; 221 return true;
154 } 222 }
155 223
156 if (response->store_birthday() != local_birthday) { 224 if (response.store_birthday() != local_birthday) {
157 LOG(WARNING) << "Birthday changed, showing syncer stuck"; 225 LOG(WARNING) << "Birthday changed, showing syncer stuck";
158 return false; 226 return false;
159 } 227 }
160 228
161 return true; 229 return true;
162 } 230 }
163 231
164 // static 232 // static
165 void SyncerProtoUtil::AddRequestBirthday(syncable::Directory* dir, 233 void SyncerProtoUtil::AddRequestBirthday(syncable::Directory* dir,
166 ClientToServerMessage* msg) { 234 ClientToServerMessage* msg) {
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after
258 if (!message.has_get_updates()) 326 if (!message.has_get_updates())
259 return false; 327 return false;
260 DCHECK_LT(0, message.get_updates().from_progress_marker_size()); 328 DCHECK_LT(0, message.get_updates().from_progress_marker_size());
261 for (int i = 0; i < message.get_updates().from_progress_marker_size(); ++i) { 329 for (int i = 0; i < message.get_updates().from_progress_marker_size(); ++i) {
262 if (!message.get_updates().from_progress_marker(i).token().empty()) 330 if (!message.get_updates().from_progress_marker(i).token().empty())
263 return false; 331 return false;
264 } 332 }
265 return true; 333 return true;
266 } 334 }
267 335
268 SyncProtocolErrorType ConvertSyncProtocolErrorTypePBToLocalType(
269 const sync_pb::SyncEnums::ErrorType& error_type) {
270 switch (error_type) {
271 case sync_pb::SyncEnums::SUCCESS:
272 return SYNC_SUCCESS;
273 case sync_pb::SyncEnums::NOT_MY_BIRTHDAY:
274 return NOT_MY_BIRTHDAY;
275 case sync_pb::SyncEnums::THROTTLED:
276 return THROTTLED;
277 case sync_pb::SyncEnums::CLEAR_PENDING:
278 return CLEAR_PENDING;
279 case sync_pb::SyncEnums::TRANSIENT_ERROR:
280 return TRANSIENT_ERROR;
281 case sync_pb::SyncEnums::MIGRATION_DONE:
282 return MIGRATION_DONE;
283 case sync_pb::SyncEnums::UNKNOWN:
284 return UNKNOWN_ERROR;
285 case sync_pb::SyncEnums::USER_NOT_ACTIVATED:
286 case sync_pb::SyncEnums::AUTH_INVALID:
287 case sync_pb::SyncEnums::ACCESS_DENIED:
288 return INVALID_CREDENTIAL;
289 default:
290 NOTREACHED();
291 return UNKNOWN_ERROR;
292 }
293 }
294
295 ClientAction ConvertClientActionPBToLocalClientAction(
296 const sync_pb::SyncEnums::Action& action) {
297 switch (action) {
298 case sync_pb::SyncEnums::UPGRADE_CLIENT:
299 return UPGRADE_CLIENT;
300 case sync_pb::SyncEnums::CLEAR_USER_DATA_AND_RESYNC:
301 return CLEAR_USER_DATA_AND_RESYNC;
302 case sync_pb::SyncEnums::ENABLE_SYNC_ON_ACCOUNT:
303 return ENABLE_SYNC_ON_ACCOUNT;
304 case sync_pb::SyncEnums::STOP_AND_RESTART_SYNC:
305 return STOP_AND_RESTART_SYNC;
306 case sync_pb::SyncEnums::DISABLE_SYNC_ON_CLIENT:
307 return DISABLE_SYNC_ON_CLIENT;
308 case sync_pb::SyncEnums::UNKNOWN_ACTION:
309 return UNKNOWN_ACTION;
310 default:
311 NOTREACHED();
312 return UNKNOWN_ACTION;
313 }
314 }
315
316 SyncProtocolError ConvertErrorPBToLocalType(
317 const ClientToServerResponse::Error& error) {
318 SyncProtocolError sync_protocol_error;
319 sync_protocol_error.error_type = ConvertSyncProtocolErrorTypePBToLocalType(
320 error.error_type());
321 sync_protocol_error.error_description = error.error_description();
322 sync_protocol_error.url = error.url();
323 sync_protocol_error.action = ConvertClientActionPBToLocalClientAction(
324 error.action());
325
326 if (error.error_data_type_ids_size() > 0) {
327 // THROTTLED is currently the only error code that uses |error_data_types|.
328 DCHECK_EQ(error.error_type(), sync_pb::SyncEnums::THROTTLED);
329 for (int i = 0; i < error.error_data_type_ids_size(); ++i) {
330 int field_number = error.error_data_type_ids(i);
331 ModelType model_type =
332 GetModelTypeFromSpecificsFieldNumber(field_number);
333 if (!IsRealDataType(model_type)) {
334 NOTREACHED() << "Unknown field number " << field_number;
335 continue;
336 }
337 sync_protocol_error.error_data_types.Put(model_type);
338 }
339 }
340
341 return sync_protocol_error;
342 }
343
344 // TODO(lipalani) : Rename these function names as per the CR for issue 7740067. 336 // TODO(lipalani) : Rename these function names as per the CR for issue 7740067.
345 SyncProtocolError ConvertLegacyErrorCodeToNewError( 337 SyncProtocolError ConvertLegacyErrorCodeToNewError(
346 const sync_pb::SyncEnums::ErrorType& error_type) { 338 const sync_pb::SyncEnums::ErrorType& error_type) {
347 SyncProtocolError error; 339 SyncProtocolError error;
348 error.error_type = ConvertSyncProtocolErrorTypePBToLocalType(error_type); 340 error.error_type = ConvertSyncProtocolErrorTypePBToLocalType(error_type);
349 if (error_type == sync_pb::SyncEnums::CLEAR_PENDING || 341 if (error_type == sync_pb::SyncEnums::CLEAR_PENDING ||
350 error_type == sync_pb::SyncEnums::NOT_MY_BIRTHDAY) { 342 error_type == sync_pb::SyncEnums::NOT_MY_BIRTHDAY) {
351 error.action = DISABLE_SYNC_ON_CLIENT; 343 error.action = DISABLE_SYNC_ON_CLIENT;
352 } // There is no other action we can compute for legacy server. 344 } // There is no other action we can compute for legacy server.
353 return error; 345 return error;
354 } 346 }
355 347
356 } // namespace 348 } // namespace
357 349
358 // static 350 // static
359 SyncerError SyncerProtoUtil::PostClientToServerMessage( 351 SyncerError SyncerProtoUtil::PostClientToServerMessage(
360 ClientToServerMessage* msg, 352 ClientToServerMessage* msg,
361 ClientToServerResponse* response, 353 ClientToServerResponse* response,
362 SyncSession* session) { 354 SyncSession* session) {
363
364 CHECK(response); 355 CHECK(response);
365 DCHECK(!msg->get_updates().has_from_timestamp()); // Deprecated. 356 DCHECK(!msg->get_updates().has_from_timestamp()); // Deprecated.
366 DCHECK(!msg->get_updates().has_requested_types()); // Deprecated. 357 DCHECK(!msg->get_updates().has_requested_types()); // Deprecated.
367 358
368 // Add must-have fields. 359 // Add must-have fields.
369 SetProtocolVersion(msg); 360 SetProtocolVersion(msg);
370 AddRequestBirthday(session->context()->directory(), msg); 361 AddRequestBirthday(session->context()->directory(), msg);
371 DCHECK(msg->has_store_birthday() || IsVeryFirstGetUpdates(*msg)); 362 DCHECK(msg->has_store_birthday() || IsVeryFirstGetUpdates(*msg));
372 AddBagOfChips(session->context()->directory(), msg); 363 AddBagOfChips(session->context()->directory(), msg);
373 msg->set_api_key(google_apis::GetAPIKey()); 364 msg->set_api_key(google_apis::GetAPIKey());
(...skipping 19 matching lines...) Expand all
393 LogClientToServerResponse(*response); 384 LogClientToServerResponse(*response);
394 session->context()->traffic_recorder()->RecordClientToServerResponse( 385 session->context()->traffic_recorder()->RecordClientToServerResponse(
395 *response); 386 *response);
396 387
397 // Persist a bag of chips if it has been sent by the server. 388 // Persist a bag of chips if it has been sent by the server.
398 PersistBagOfChips(dir, *response); 389 PersistBagOfChips(dir, *response);
399 390
400 SyncProtocolError sync_protocol_error; 391 SyncProtocolError sync_protocol_error;
401 392
402 // Birthday mismatch overrides any error that is sent by the server. 393 // Birthday mismatch overrides any error that is sent by the server.
403 if (!VerifyResponseBirthday(dir, response)) { 394 if (!VerifyResponseBirthday(*response, dir)) {
404 sync_protocol_error.error_type = NOT_MY_BIRTHDAY; 395 sync_protocol_error.error_type = NOT_MY_BIRTHDAY;
405 sync_protocol_error.action = 396 sync_protocol_error.action =
406 DISABLE_SYNC_ON_CLIENT; 397 DISABLE_SYNC_ON_CLIENT;
407 } else if (response->has_error()) { 398 } else if (response->has_error()) {
408 // This is a new server. Just get the error from the protocol. 399 // This is a new server. Just get the error from the protocol.
409 sync_protocol_error = ConvertErrorPBToLocalType(response->error()); 400 sync_protocol_error = ConvertErrorPBToLocalType(response->error());
410 } else { 401 } else {
411 // Legacy server implementation. Compute the error based on |error_code|. 402 // Legacy server implementation. Compute the error based on |error_code|.
412 sync_protocol_error = ConvertLegacyErrorCodeToNewError( 403 sync_protocol_error = ConvertLegacyErrorCodeToNewError(
413 response->error_code()); 404 response->error_code());
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
458 case THROTTLED: 449 case THROTTLED:
459 LOG(WARNING) << "Client silenced by server."; 450 LOG(WARNING) << "Client silenced by server.";
460 HandleThrottleError(sync_protocol_error, 451 HandleThrottleError(sync_protocol_error,
461 base::TimeTicks::Now() + GetThrottleDelay(*response), 452 base::TimeTicks::Now() + GetThrottleDelay(*response),
462 session->context()->throttled_data_type_tracker(), 453 session->context()->throttled_data_type_tracker(),
463 session->delegate()); 454 session->delegate());
464 return SERVER_RETURN_THROTTLED; 455 return SERVER_RETURN_THROTTLED;
465 case TRANSIENT_ERROR: 456 case TRANSIENT_ERROR:
466 return SERVER_RETURN_TRANSIENT_ERROR; 457 return SERVER_RETURN_TRANSIENT_ERROR;
467 case MIGRATION_DONE: 458 case MIGRATION_DONE:
468 HandleMigrationDoneResponse(response, session); 459 LOG_IF(ERROR, 0 >= response->migrated_data_type_id_size())
460 << "MIGRATION_DONE but no types specified.";
461 // TODO(akalin): This should be a set union.
462 session->mutable_status_controller()->
463 set_types_needing_local_migration(GetTypesToMigrate(*response));
469 return SERVER_RETURN_MIGRATION_DONE; 464 return SERVER_RETURN_MIGRATION_DONE;
470 case CLEAR_PENDING: 465 case CLEAR_PENDING:
471 return SERVER_RETURN_CLEAR_PENDING; 466 return SERVER_RETURN_CLEAR_PENDING;
472 case NOT_MY_BIRTHDAY: 467 case NOT_MY_BIRTHDAY:
473 return SERVER_RETURN_NOT_MY_BIRTHDAY; 468 return SERVER_RETURN_NOT_MY_BIRTHDAY;
474 default: 469 default:
475 NOTREACHED(); 470 NOTREACHED();
476 return UNSET; 471 return UNSET;
477 } 472 }
478 } 473 }
(...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after
608 std::string SyncerProtoUtil::ClientToServerResponseDebugString( 603 std::string SyncerProtoUtil::ClientToServerResponseDebugString(
609 const ClientToServerResponse& response) { 604 const ClientToServerResponse& response) {
610 // Add more handlers as needed. 605 // Add more handlers as needed.
611 std::string output; 606 std::string output;
612 if (response.has_get_updates()) 607 if (response.has_get_updates())
613 output.append(GetUpdatesResponseString(response.get_updates())); 608 output.append(GetUpdatesResponseString(response.get_updates()));
614 return output; 609 return output;
615 } 610 }
616 611
617 } // namespace syncer 612 } // namespace syncer
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698