Merge Chromium + Blink git repositories
[chromium-blink-merge.git] / sync / test / engine / mock_connection_manager.cc
blobcb07db48bd8404744c29b803c97186066ba23108
1 // Copyright 2012 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 // Mock ServerConnectionManager class for use in client regression tests.
7 #include "sync/test/engine/mock_connection_manager.h"
9 #include <map>
11 #include "base/location.h"
12 #include "base/strings/stringprintf.h"
13 #include "sync/engine/syncer_proto_util.h"
14 #include "sync/protocol/bookmark_specifics.pb.h"
15 #include "sync/syncable/directory.h"
16 #include "sync/syncable/syncable_write_transaction.h"
17 #include "sync/test/engine/test_id_factory.h"
18 #include "testing/gtest/include/gtest/gtest.h"
20 using std::find;
21 using std::map;
22 using std::string;
23 using sync_pb::ClientToServerMessage;
24 using sync_pb::CommitMessage;
25 using sync_pb::CommitResponse;
26 using sync_pb::GetUpdatesMessage;
27 using sync_pb::SyncEnums;
29 namespace syncer {
31 using syncable::WriteTransaction;
33 static char kValidAuthToken[] = "AuthToken";
34 static char kCacheGuid[] = "kqyg7097kro6GSUod+GSg==";
36 MockConnectionManager::MockConnectionManager(syncable::Directory* directory,
37 CancelationSignal* signal)
38 : ServerConnectionManager("unused", 0, false, signal),
39 server_reachable_(true),
40 conflict_all_commits_(false),
41 conflict_n_commits_(0),
42 next_new_id_(10000),
43 store_birthday_("Store BDay!"),
44 store_birthday_sent_(false),
45 client_stuck_(false),
46 countdown_to_postbuffer_fail_(0),
47 directory_(directory),
48 mid_commit_observer_(NULL),
49 throttling_(false),
50 partialThrottling_(false),
51 fail_with_auth_invalid_(false),
52 fail_non_periodic_get_updates_(false),
53 next_position_in_parent_(2),
54 use_legacy_bookmarks_protocol_(false),
55 num_get_updates_requests_(0) {
56 SetNewTimestamp(0);
57 SetAuthToken(kValidAuthToken);
60 MockConnectionManager::~MockConnectionManager() {
61 EXPECT_TRUE(update_queue_.empty()) << "Unfetched updates.";
64 void MockConnectionManager::SetCommitTimeRename(const string& prepend) {
65 commit_time_rename_prepended_string_ = prepend;
68 void MockConnectionManager::SetMidCommitCallback(
69 const base::Closure& callback) {
70 mid_commit_callback_ = callback;
73 void MockConnectionManager::SetMidCommitObserver(
74 MockConnectionManager::MidCommitObserver* observer) {
75 mid_commit_observer_ = observer;
78 bool MockConnectionManager::PostBufferToPath(PostBufferParams* params,
79 const string& path,
80 const string& auth_token,
81 ScopedServerStatusWatcher* watcher) {
82 ClientToServerMessage post;
83 CHECK(post.ParseFromString(params->buffer_in));
84 CHECK(post.has_protocol_version());
85 CHECK(post.has_api_key());
86 CHECK(post.has_bag_of_chips());
88 requests_.push_back(post);
89 client_stuck_ = post.sync_problem_detected();
90 sync_pb::ClientToServerResponse response;
91 response.Clear();
93 if (directory_) {
94 // If the Directory's locked when we do this, it's a problem as in normal
95 // use this function could take a while to return because it accesses the
96 // network. As we can't test this we do the next best thing and hang here
97 // when there's an issue.
98 CHECK(directory_->good());
99 WriteTransaction wt(FROM_HERE, syncable::UNITTEST, directory_);
102 if (auth_token.empty()) {
103 params->response.server_status = HttpResponse::SYNC_AUTH_ERROR;
104 return false;
107 if (auth_token != kValidAuthToken) {
108 // Simulate server-side auth failure.
109 params->response.server_status = HttpResponse::SYNC_AUTH_ERROR;
110 InvalidateAndClearAuthToken();
113 if (--countdown_to_postbuffer_fail_ == 0) {
114 // Fail as countdown hits zero.
115 params->response.server_status = HttpResponse::SYNC_SERVER_ERROR;
116 return false;
119 if (!server_reachable_) {
120 params->response.server_status = HttpResponse::CONNECTION_UNAVAILABLE;
121 return false;
124 // Default to an ok connection.
125 params->response.server_status = HttpResponse::SERVER_CONNECTION_OK;
126 response.set_error_code(SyncEnums::SUCCESS);
127 const string current_store_birthday = store_birthday();
128 response.set_store_birthday(current_store_birthday);
129 if (post.has_store_birthday() && post.store_birthday() !=
130 current_store_birthday) {
131 response.set_error_code(SyncEnums::NOT_MY_BIRTHDAY);
132 response.set_error_message("Merry Unbirthday!");
133 response.SerializeToString(&params->buffer_out);
134 store_birthday_sent_ = true;
135 return true;
137 bool result = true;
138 EXPECT_TRUE(!store_birthday_sent_ || post.has_store_birthday() ||
139 post.message_contents() == ClientToServerMessage::AUTHENTICATE ||
140 post.message_contents() ==
141 ClientToServerMessage::CLEAR_SERVER_DATA);
142 store_birthday_sent_ = true;
144 if (post.message_contents() == ClientToServerMessage::COMMIT) {
145 ProcessCommit(&post, &response);
146 } else if (post.message_contents() == ClientToServerMessage::GET_UPDATES) {
147 ProcessGetUpdates(&post, &response);
148 } else if (post.message_contents() ==
149 ClientToServerMessage::CLEAR_SERVER_DATA) {
150 ProcessClearServerData(&post, &response);
151 } else {
152 EXPECT_TRUE(false) << "Unknown/unsupported ClientToServerMessage";
153 return false;
157 base::AutoLock lock(response_code_override_lock_);
158 if (throttling_) {
159 response.set_error_code(SyncEnums::THROTTLED);
160 throttling_ = false;
163 if (partialThrottling_) {
164 sync_pb::ClientToServerResponse_Error* response_error =
165 response.mutable_error();
166 response_error->set_error_type(SyncEnums::PARTIAL_FAILURE);
167 for (ModelTypeSet::Iterator it = throttled_type_.First(); it.Good();
168 it.Inc()) {
169 response_error->add_error_data_type_ids(
170 GetSpecificsFieldNumberFromModelType(it.Get()));
172 partialThrottling_ = false;
175 if (fail_with_auth_invalid_)
176 response.set_error_code(SyncEnums::AUTH_INVALID);
179 response.SerializeToString(&params->buffer_out);
180 if (post.message_contents() == ClientToServerMessage::COMMIT &&
181 !mid_commit_callback_.is_null()) {
182 mid_commit_callback_.Run();
183 mid_commit_callback_.Reset();
185 if (mid_commit_observer_) {
186 mid_commit_observer_->Observe();
189 return result;
192 sync_pb::GetUpdatesResponse* MockConnectionManager::GetUpdateResponse() {
193 if (update_queue_.empty()) {
194 NextUpdateBatch();
196 return &update_queue_.back();
199 void MockConnectionManager::AddDefaultBookmarkData(sync_pb::SyncEntity* entity,
200 bool is_folder) {
201 if (use_legacy_bookmarks_protocol_) {
202 sync_pb::SyncEntity_BookmarkData* data = entity->mutable_bookmarkdata();
203 data->set_bookmark_folder(is_folder);
205 if (!is_folder) {
206 data->set_bookmark_url("http://google.com");
208 } else {
209 entity->set_folder(is_folder);
210 entity->mutable_specifics()->mutable_bookmark();
211 if (!is_folder) {
212 entity->mutable_specifics()->mutable_bookmark()->
213 set_url("http://google.com");
218 sync_pb::SyncEntity* MockConnectionManager::AddUpdateDirectory(
219 int id,
220 int parent_id,
221 const string& name,
222 int64 version,
223 int64 sync_ts,
224 const std::string& originator_cache_guid,
225 const std::string& originator_client_item_id) {
226 return AddUpdateDirectory(TestIdFactory::FromNumber(id),
227 TestIdFactory::FromNumber(parent_id),
228 name,
229 version,
230 sync_ts,
231 originator_cache_guid,
232 originator_client_item_id);
235 void MockConnectionManager::SetGUClientCommand(
236 sync_pb::ClientCommand* command) {
237 gu_client_command_.reset(command);
240 void MockConnectionManager::SetCommitClientCommand(
241 sync_pb::ClientCommand* command) {
242 commit_client_command_.reset(command);
245 void MockConnectionManager::SetTransientErrorId(syncable::Id id) {
246 transient_error_ids_.push_back(id);
249 sync_pb::SyncEntity* MockConnectionManager::AddUpdateBookmark(
250 int id,
251 int parent_id,
252 const string& name,
253 int64 version,
254 int64 sync_ts,
255 const string& originator_client_item_id,
256 const string& originator_cache_guid) {
257 return AddUpdateBookmark(TestIdFactory::FromNumber(id),
258 TestIdFactory::FromNumber(parent_id),
259 name,
260 version,
261 sync_ts,
262 originator_client_item_id,
263 originator_cache_guid);
266 sync_pb::SyncEntity* MockConnectionManager::AddUpdateSpecifics(
267 int id,
268 int parent_id,
269 const string& name,
270 int64 version,
271 int64 sync_ts,
272 bool is_dir,
273 int64 position,
274 const sync_pb::EntitySpecifics& specifics) {
275 sync_pb::SyncEntity* ent = AddUpdateMeta(
276 TestIdFactory::FromNumber(id).GetServerId(),
277 TestIdFactory::FromNumber(parent_id).GetServerId(),
278 name, version, sync_ts);
279 ent->set_position_in_parent(position);
280 ent->mutable_specifics()->CopyFrom(specifics);
281 ent->set_folder(is_dir);
282 return ent;
285 sync_pb::SyncEntity* MockConnectionManager::AddUpdateSpecifics(
286 int id,
287 int parent_id,
288 const string& name,
289 int64 version,
290 int64 sync_ts,
291 bool is_dir,
292 int64 position,
293 const sync_pb::EntitySpecifics& specifics,
294 const string& originator_cache_guid,
295 const string& originator_client_item_id) {
296 sync_pb::SyncEntity* ent = AddUpdateSpecifics(
297 id, parent_id, name, version, sync_ts, is_dir, position, specifics);
298 ent->set_originator_cache_guid(originator_cache_guid);
299 ent->set_originator_client_item_id(originator_client_item_id);
300 return ent;
303 sync_pb::SyncEntity* MockConnectionManager::SetNigori(
304 int id,
305 int64 version,
306 int64 sync_ts,
307 const sync_pb::EntitySpecifics& specifics) {
308 sync_pb::SyncEntity* ent = GetUpdateResponse()->add_entries();
309 ent->set_id_string(TestIdFactory::FromNumber(id).GetServerId());
310 ent->set_parent_id_string(TestIdFactory::FromNumber(0).GetServerId());
311 ent->set_server_defined_unique_tag(ModelTypeToRootTag(NIGORI));
312 ent->set_name("Nigori");
313 ent->set_non_unique_name("Nigori");
314 ent->set_version(version);
315 ent->set_sync_timestamp(sync_ts);
316 ent->set_mtime(sync_ts);
317 ent->set_ctime(1);
318 ent->set_position_in_parent(0);
319 ent->set_folder(false);
320 ent->mutable_specifics()->CopyFrom(specifics);
321 return ent;
324 sync_pb::SyncEntity* MockConnectionManager::AddUpdatePref(
325 const string& id,
326 const string& parent_id,
327 const string& client_tag,
328 int64 version,
329 int64 sync_ts) {
330 sync_pb::SyncEntity* ent =
331 AddUpdateMeta(id, parent_id, " ", version, sync_ts);
333 ent->set_client_defined_unique_tag(client_tag);
335 sync_pb::EntitySpecifics specifics;
336 AddDefaultFieldValue(PREFERENCES, &specifics);
337 ent->mutable_specifics()->CopyFrom(specifics);
339 return ent;
342 sync_pb::SyncEntity* MockConnectionManager::AddUpdateFull(
343 const string& id,
344 const string& parent_id,
345 const string& name,
346 int64 version,
347 int64 sync_ts,
348 bool is_dir) {
349 sync_pb::SyncEntity* ent =
350 AddUpdateMeta(id, parent_id, name, version, sync_ts);
351 AddDefaultBookmarkData(ent, is_dir);
352 return ent;
355 sync_pb::SyncEntity* MockConnectionManager::AddUpdateMeta(
356 const string& id,
357 const string& parent_id,
358 const string& name,
359 int64 version,
360 int64 sync_ts) {
361 sync_pb::SyncEntity* ent = GetUpdateResponse()->add_entries();
362 ent->set_id_string(id);
363 ent->set_parent_id_string(parent_id);
364 ent->set_non_unique_name(name);
365 ent->set_name(name);
366 ent->set_version(version);
367 ent->set_sync_timestamp(sync_ts);
368 ent->set_mtime(sync_ts);
369 ent->set_ctime(1);
370 ent->set_position_in_parent(GeneratePositionInParent());
372 // This isn't perfect, but it works well enough. This is an update, which
373 // means the ID is a server ID, which means it never changes. By making
374 // kCacheGuid also never change, we guarantee that the same item always has
375 // the same originator_cache_guid and originator_client_item_id.
377 // Unfortunately, neither this class nor the tests that use it explicitly
378 // track sync entitites, so supporting proper cache guids and client item IDs
379 // would require major refactoring. The ID used here ought to be the "c-"
380 // style ID that was sent up on the commit.
381 ent->set_originator_cache_guid(kCacheGuid);
382 ent->set_originator_client_item_id(id);
384 return ent;
387 sync_pb::SyncEntity* MockConnectionManager::AddUpdateDirectory(
388 const string& id,
389 const string& parent_id,
390 const string& name,
391 int64 version,
392 int64 sync_ts,
393 const std::string& originator_cache_guid,
394 const std::string& originator_client_item_id) {
395 sync_pb::SyncEntity* ret =
396 AddUpdateFull(id, parent_id, name, version, sync_ts, true);
397 ret->set_originator_cache_guid(originator_cache_guid);
398 ret->set_originator_client_item_id(originator_client_item_id);
399 return ret;
402 sync_pb::SyncEntity* MockConnectionManager::AddUpdateBookmark(
403 const string& id,
404 const string& parent_id,
405 const string& name,
406 int64 version,
407 int64 sync_ts,
408 const string& originator_cache_guid,
409 const string& originator_client_item_id) {
410 sync_pb::SyncEntity* ret =
411 AddUpdateFull(id, parent_id, name, version, sync_ts, false);
412 ret->set_originator_cache_guid(originator_cache_guid);
413 ret->set_originator_client_item_id(originator_client_item_id);
414 return ret;
417 sync_pb::SyncEntity* MockConnectionManager::AddUpdateFromLastCommit() {
418 EXPECT_EQ(1, last_sent_commit().entries_size());
419 EXPECT_EQ(1, last_commit_response().entryresponse_size());
420 EXPECT_EQ(CommitResponse::SUCCESS,
421 last_commit_response().entryresponse(0).response_type());
423 if (last_sent_commit().entries(0).deleted()) {
424 ModelType type = GetModelType(last_sent_commit().entries(0));
425 AddUpdateTombstone(syncable::Id::CreateFromServerId(
426 last_sent_commit().entries(0).id_string()), type);
427 } else {
428 sync_pb::SyncEntity* ent = GetUpdateResponse()->add_entries();
429 ent->CopyFrom(last_sent_commit().entries(0));
430 ent->clear_insert_after_item_id();
431 ent->clear_old_parent_id();
432 ent->set_position_in_parent(
433 last_commit_response().entryresponse(0).position_in_parent());
434 ent->set_version(
435 last_commit_response().entryresponse(0).version());
436 ent->set_id_string(
437 last_commit_response().entryresponse(0).id_string());
439 // This is the same hack as in AddUpdateMeta. See the comment in that
440 // function for more information.
441 ent->set_originator_cache_guid(kCacheGuid);
442 ent->set_originator_client_item_id(
443 last_commit_response().entryresponse(0).id_string());
445 if (last_sent_commit().entries(0).has_unique_position()) {
446 ent->mutable_unique_position()->CopyFrom(
447 last_sent_commit().entries(0).unique_position());
450 // Tests don't currently care about the following:
451 // parent_id_string, name, non_unique_name.
453 return GetMutableLastUpdate();
456 void MockConnectionManager::AddUpdateTombstone(
457 const syncable::Id& id,
458 ModelType type) {
459 // Tombstones have only the ID set and dummy values for the required fields.
460 sync_pb::SyncEntity* ent = GetUpdateResponse()->add_entries();
461 ent->set_id_string(id.GetServerId());
462 ent->set_version(0);
463 ent->set_name("");
464 ent->set_deleted(true);
466 // Make sure we can still extract the ModelType from this tombstone.
467 AddDefaultFieldValue(type, ent->mutable_specifics());
470 void MockConnectionManager::SetLastUpdateDeleted() {
471 // Tombstones have only the ID set. Wipe anything else.
472 string id_string = GetMutableLastUpdate()->id_string();
473 ModelType type = GetModelType(*GetMutableLastUpdate());
474 GetUpdateResponse()->mutable_entries()->RemoveLast();
475 AddUpdateTombstone(syncable::Id::CreateFromServerId(id_string), type);
478 void MockConnectionManager::SetLastUpdateOriginatorFields(
479 const string& client_id,
480 const string& entry_id) {
481 GetMutableLastUpdate()->set_originator_cache_guid(client_id);
482 GetMutableLastUpdate()->set_originator_client_item_id(entry_id);
485 void MockConnectionManager::SetLastUpdateServerTag(const string& tag) {
486 GetMutableLastUpdate()->set_server_defined_unique_tag(tag);
489 void MockConnectionManager::SetLastUpdateClientTag(const string& tag) {
490 GetMutableLastUpdate()->set_client_defined_unique_tag(tag);
493 void MockConnectionManager::SetLastUpdatePosition(int64 server_position) {
494 GetMutableLastUpdate()->set_position_in_parent(server_position);
497 void MockConnectionManager::SetNewTimestamp(int ts) {
498 next_token_ = base::StringPrintf("mock connection ts = %d", ts);
499 ApplyToken();
502 void MockConnectionManager::ApplyToken() {
503 if (!update_queue_.empty()) {
504 GetUpdateResponse()->clear_new_progress_marker();
505 sync_pb::DataTypeProgressMarker* new_marker =
506 GetUpdateResponse()->add_new_progress_marker();
507 new_marker->set_data_type_id(-1); // Invalid -- clients shouldn't see.
508 new_marker->set_token(next_token_);
512 void MockConnectionManager::SetChangesRemaining(int64 timestamp) {
513 GetUpdateResponse()->set_changes_remaining(timestamp);
516 void MockConnectionManager::ProcessGetUpdates(
517 sync_pb::ClientToServerMessage* csm,
518 sync_pb::ClientToServerResponse* response) {
519 CHECK(csm->has_get_updates());
520 ASSERT_EQ(csm->message_contents(), ClientToServerMessage::GET_UPDATES);
521 const GetUpdatesMessage& gu = csm->get_updates();
522 num_get_updates_requests_++;
523 EXPECT_FALSE(gu.has_from_timestamp());
524 EXPECT_FALSE(gu.has_requested_types());
526 if (fail_non_periodic_get_updates_) {
527 EXPECT_EQ(sync_pb::GetUpdatesCallerInfo::PERIODIC,
528 gu.caller_info().source());
531 // Verify that the items we're about to send back to the client are of
532 // the types requested by the client. If this fails, it probably indicates
533 // a test bug.
534 EXPECT_TRUE(gu.fetch_folders());
535 EXPECT_FALSE(gu.has_requested_types());
536 if (update_queue_.empty()) {
537 GetUpdateResponse();
539 sync_pb::GetUpdatesResponse* updates = &update_queue_.front();
540 for (int i = 0; i < updates->entries_size(); ++i) {
541 if (!updates->entries(i).deleted()) {
542 ModelType entry_type = GetModelType(updates->entries(i));
543 EXPECT_TRUE(
544 IsModelTypePresentInSpecifics(gu.from_progress_marker(), entry_type))
545 << "Syncer did not request updates being provided by the test.";
549 response->mutable_get_updates()->CopyFrom(*updates);
551 // Set appropriate progress markers, overriding the value squirreled
552 // away by ApplyToken().
553 std::string token = response->get_updates().new_progress_marker(0).token();
554 response->mutable_get_updates()->clear_new_progress_marker();
555 for (int i = 0; i < gu.from_progress_marker_size(); ++i) {
556 sync_pb::DataTypeProgressMarker* new_marker =
557 response->mutable_get_updates()->add_new_progress_marker();
558 new_marker->set_data_type_id(gu.from_progress_marker(i).data_type_id());
559 new_marker->set_token(token);
562 // Fill the keystore key if requested.
563 if (gu.need_encryption_key())
564 response->mutable_get_updates()->add_encryption_keys(keystore_key_);
566 update_queue_.pop_front();
568 if (gu_client_command_) {
569 response->mutable_client_command()->CopyFrom(*gu_client_command_.get());
573 void MockConnectionManager::SetKeystoreKey(const std::string& key) {
574 // Note: this is not a thread-safe set, ok for now. NOT ok if tests
575 // run the syncer on the background thread while this method is called.
576 keystore_key_ = key;
579 bool MockConnectionManager::ShouldConflictThisCommit() {
580 bool conflict = false;
581 if (conflict_all_commits_) {
582 conflict = true;
583 } else if (conflict_n_commits_ > 0) {
584 conflict = true;
585 --conflict_n_commits_;
587 return conflict;
590 bool MockConnectionManager::ShouldTransientErrorThisId(syncable::Id id) {
591 return find(transient_error_ids_.begin(), transient_error_ids_.end(), id)
592 != transient_error_ids_.end();
595 void MockConnectionManager::ProcessCommit(
596 sync_pb::ClientToServerMessage* csm,
597 sync_pb::ClientToServerResponse* response_buffer) {
598 CHECK(csm->has_commit());
599 ASSERT_EQ(csm->message_contents(), ClientToServerMessage::COMMIT);
600 map <string, string> changed_ids;
601 const CommitMessage& commit_message = csm->commit();
602 CommitResponse* commit_response = response_buffer->mutable_commit();
603 commit_messages_.push_back(new CommitMessage);
604 commit_messages_.back()->CopyFrom(commit_message);
605 map<string, sync_pb::CommitResponse_EntryResponse*> response_map;
606 for (int i = 0; i < commit_message.entries_size() ; i++) {
607 const sync_pb::SyncEntity& entry = commit_message.entries(i);
608 CHECK(entry.has_id_string());
609 string id_string = entry.id_string();
610 ASSERT_LT(entry.name().length(), 256ul) << " name probably too long. True "
611 "server name checking not implemented";
612 syncable::Id id;
613 if (entry.version() == 0) {
614 // Relies on our new item string id format. (string representation of a
615 // negative number).
616 id = syncable::Id::CreateFromClientString(id_string);
617 } else {
618 id = syncable::Id::CreateFromServerId(id_string);
620 committed_ids_.push_back(id);
622 if (response_map.end() == response_map.find(id_string))
623 response_map[id_string] = commit_response->add_entryresponse();
624 sync_pb::CommitResponse_EntryResponse* er = response_map[id_string];
625 if (ShouldConflictThisCommit()) {
626 er->set_response_type(CommitResponse::CONFLICT);
627 continue;
629 if (ShouldTransientErrorThisId(id)) {
630 er->set_response_type(CommitResponse::TRANSIENT_ERROR);
631 continue;
633 er->set_response_type(CommitResponse::SUCCESS);
634 er->set_version(entry.version() + 1);
635 if (!commit_time_rename_prepended_string_.empty()) {
636 // Commit time rename sent down from the server.
637 er->set_name(commit_time_rename_prepended_string_ + entry.name());
639 string parent_id_string = entry.parent_id_string();
640 // Remap id's we've already assigned.
641 if (changed_ids.end() != changed_ids.find(parent_id_string)) {
642 parent_id_string = changed_ids[parent_id_string];
643 er->set_parent_id_string(parent_id_string);
645 if (entry.has_version() && 0 != entry.version()) {
646 er->set_id_string(id_string); // Allows verification.
647 } else {
648 string new_id = base::StringPrintf("mock_server:%d", next_new_id_++);
649 changed_ids[id_string] = new_id;
650 er->set_id_string(new_id);
653 commit_responses_.push_back(new CommitResponse(*commit_response));
655 if (commit_client_command_) {
656 response_buffer->mutable_client_command()->CopyFrom(
657 *commit_client_command_.get());
661 void MockConnectionManager::ProcessClearServerData(
662 sync_pb::ClientToServerMessage* csm,
663 sync_pb::ClientToServerResponse* response) {
664 CHECK(csm->has_clear_server_data());
665 ASSERT_EQ(csm->message_contents(), ClientToServerMessage::CLEAR_SERVER_DATA);
666 response->mutable_clear_server_data();
669 sync_pb::SyncEntity* MockConnectionManager::AddUpdateDirectory(
670 syncable::Id id,
671 syncable::Id parent_id,
672 const string& name,
673 int64 version,
674 int64 sync_ts,
675 const string& originator_cache_guid,
676 const string& originator_client_item_id) {
677 return AddUpdateDirectory(id.GetServerId(), parent_id.GetServerId(),
678 name, version, sync_ts, originator_cache_guid,
679 originator_client_item_id);
682 sync_pb::SyncEntity* MockConnectionManager::AddUpdateBookmark(
683 syncable::Id id,
684 syncable::Id parent_id,
685 const string& name,
686 int64 version,
687 int64 sync_ts,
688 const string& originator_cache_guid,
689 const string& originator_client_item_id) {
690 return AddUpdateBookmark(id.GetServerId(), parent_id.GetServerId(),
691 name, version, sync_ts, originator_cache_guid,
692 originator_client_item_id);
695 sync_pb::SyncEntity* MockConnectionManager::GetMutableLastUpdate() {
696 sync_pb::GetUpdatesResponse* updates = GetUpdateResponse();
697 EXPECT_GT(updates->entries_size(), 0);
698 return updates->mutable_entries()->Mutable(updates->entries_size() - 1);
701 void MockConnectionManager::NextUpdateBatch() {
702 update_queue_.push_back(sync_pb::GetUpdatesResponse::default_instance());
703 SetChangesRemaining(0);
704 ApplyToken();
707 const CommitMessage& MockConnectionManager::last_sent_commit() const {
708 EXPECT_TRUE(!commit_messages_.empty());
709 return *commit_messages_.back();
712 const CommitResponse& MockConnectionManager::last_commit_response() const {
713 EXPECT_TRUE(!commit_responses_.empty());
714 return *commit_responses_.back();
717 const sync_pb::ClientToServerMessage&
718 MockConnectionManager::last_request() const {
719 EXPECT_TRUE(!requests_.empty());
720 return requests_.back();
723 const std::vector<sync_pb::ClientToServerMessage>&
724 MockConnectionManager::requests() const {
725 return requests_;
728 bool MockConnectionManager::IsModelTypePresentInSpecifics(
729 const google::protobuf::RepeatedPtrField<
730 sync_pb::DataTypeProgressMarker>& filter,
731 ModelType value) {
732 int data_type_id = GetSpecificsFieldNumberFromModelType(value);
733 for (int i = 0; i < filter.size(); ++i) {
734 if (filter.Get(i).data_type_id() == data_type_id) {
735 return true;
738 return false;
741 sync_pb::DataTypeProgressMarker const*
742 MockConnectionManager::GetProgressMarkerForType(
743 const google::protobuf::RepeatedPtrField<
744 sync_pb::DataTypeProgressMarker>& filter,
745 ModelType value) {
746 int data_type_id = GetSpecificsFieldNumberFromModelType(value);
747 for (int i = 0; i < filter.size(); ++i) {
748 if (filter.Get(i).data_type_id() == data_type_id) {
749 return &(filter.Get(i));
752 return NULL;
755 void MockConnectionManager::SetServerReachable() {
756 server_reachable_ = true;
759 void MockConnectionManager::SetServerNotReachable() {
760 server_reachable_ = false;
763 void MockConnectionManager::UpdateConnectionStatus() {
764 if (!server_reachable_) {
765 server_status_ = HttpResponse::CONNECTION_UNAVAILABLE;
766 } else {
767 server_status_ = HttpResponse::SERVER_CONNECTION_OK;
771 void MockConnectionManager::SetServerStatus(
772 HttpResponse::ServerConnectionCode server_status) {
773 server_status_ = server_status;
776 } // namespace syncer