mock_connection_manager.cc revision 2a99a7e74a7f215066514fe81d2bfa6639d9eddd
12a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Copyright 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Mock ServerConnectionManager class for use in client regression tests.
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "sync/test/engine/mock_connection_manager.h"
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <map>
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/location.h"
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/stringprintf.h"
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "sync/engine/syncer_proto_util.h"
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "sync/test/engine/test_id_factory.h"
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "sync/protocol/bookmark_specifics.pb.h"
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "sync/syncable/directory.h"
172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "sync/syncable/syncable_write_transaction.h"
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "sync/test/engine/test_id_factory.h"
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "testing/gtest/include/gtest/gtest.h"
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)using std::find;
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using std::map;
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using std::string;
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using sync_pb::ClientToServerMessage;
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using sync_pb::CommitMessage;
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using sync_pb::CommitResponse;
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using sync_pb::GetUpdatesMessage;
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using sync_pb::SyncEnums;
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace syncer {
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using syncable::WriteTransaction;
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static char kValidAuthToken[] = "AuthToken";
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)MockConnectionManager::MockConnectionManager(syncable::Directory* directory)
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : ServerConnectionManager("unused", 0, false),
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      server_reachable_(true),
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      conflict_all_commits_(false),
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      conflict_n_commits_(0),
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      next_new_id_(10000),
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      store_birthday_("Store BDay!"),
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      store_birthday_sent_(false),
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      client_stuck_(false),
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      commit_time_rename_prepended_string_(""),
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      countdown_to_postbuffer_fail_(0),
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      directory_(directory),
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      mid_commit_observer_(NULL),
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      throttling_(false),
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      fail_with_auth_invalid_(false),
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      fail_non_periodic_get_updates_(false),
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      gu_client_command_(NULL),
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      commit_client_command_(NULL),
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      next_position_in_parent_(2),
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      use_legacy_bookmarks_protocol_(false),
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      num_get_updates_requests_(0) {
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SetNewTimestamp(0);
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  set_auth_token(kValidAuthToken);
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)MockConnectionManager::~MockConnectionManager() {
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(update_queue_.empty()) << "Unfetched updates.";
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void MockConnectionManager::SetCommitTimeRename(string prepend) {
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  commit_time_rename_prepended_string_ = prepend;
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void MockConnectionManager::SetMidCommitCallback(
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const base::Closure& callback) {
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  mid_commit_callback_ = callback;
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void MockConnectionManager::SetMidCommitObserver(
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockConnectionManager::MidCommitObserver* observer) {
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    mid_commit_observer_ = observer;
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool MockConnectionManager::PostBufferToPath(PostBufferParams* params,
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const string& path,
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const string& auth_token,
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ScopedServerStatusWatcher* watcher) {
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ClientToServerMessage post;
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CHECK(post.ParseFromString(params->buffer_in));
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CHECK(post.has_protocol_version());
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CHECK(post.has_api_key());
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CHECK(post.has_bag_of_chips());
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  last_request_.CopyFrom(post);
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  client_stuck_ = post.sync_problem_detected();
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  sync_pb::ClientToServerResponse response;
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  response.Clear();
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (directory_) {
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // If the Directory's locked when we do this, it's a problem as in normal
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // use this function could take a while to return because it accesses the
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // network. As we can't test this we do the next best thing and hang here
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // when there's an issue.
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CHECK(directory_->good());
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    WriteTransaction wt(FROM_HERE, syncable::UNITTEST, directory_);
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (auth_token.empty()) {
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    params->response.server_status = HttpResponse::SYNC_AUTH_ERROR;
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (auth_token != kValidAuthToken) {
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Simulate server-side auth failure.
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    params->response.server_status = HttpResponse::SYNC_AUTH_ERROR;
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    InvalidateAndClearAuthToken();
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (--countdown_to_postbuffer_fail_ == 0) {
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Fail as countdown hits zero.
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    params->response.server_status = HttpResponse::SYNC_SERVER_ERROR;
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!server_reachable_) {
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    params->response.server_status = HttpResponse::CONNECTION_UNAVAILABLE;
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Default to an ok connection.
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  params->response.server_status = HttpResponse::SERVER_CONNECTION_OK;
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  response.set_error_code(SyncEnums::SUCCESS);
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const string current_store_birthday = store_birthday();
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  response.set_store_birthday(current_store_birthday);
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (post.has_store_birthday() && post.store_birthday() !=
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      current_store_birthday) {
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    response.set_error_code(SyncEnums::NOT_MY_BIRTHDAY);
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    response.set_error_message("Merry Unbirthday!");
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    response.SerializeToString(&params->buffer_out);
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    store_birthday_sent_ = true;
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return true;
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool result = true;
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(!store_birthday_sent_ || post.has_store_birthday() ||
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              post.message_contents() == ClientToServerMessage::AUTHENTICATE);
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  store_birthday_sent_ = true;
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (post.message_contents() == ClientToServerMessage::COMMIT) {
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ProcessCommit(&post, &response);
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else if (post.message_contents() == ClientToServerMessage::GET_UPDATES) {
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ProcessGetUpdates(&post, &response);
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_TRUE(false) << "Unknown/unsupported ClientToServerMessage";
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    base::AutoLock lock(response_code_override_lock_);
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (throttling_) {
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      response.set_error_code(SyncEnums::THROTTLED);
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      throttling_ = false;
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (fail_with_auth_invalid_)
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      response.set_error_code(SyncEnums::AUTH_INVALID);
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  response.SerializeToString(&params->buffer_out);
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (post.message_contents() == ClientToServerMessage::COMMIT &&
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      !mid_commit_callback_.is_null()) {
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    mid_commit_callback_.Run();
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    mid_commit_callback_.Reset();
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (mid_commit_observer_) {
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    mid_commit_observer_->Observe();
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return result;
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)sync_pb::GetUpdatesResponse* MockConnectionManager::GetUpdateResponse() {
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (update_queue_.empty()) {
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    NextUpdateBatch();
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return &update_queue_.back();
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void MockConnectionManager::AddDefaultBookmarkData(sync_pb::SyncEntity* entity,
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                   bool is_folder) {
1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (use_legacy_bookmarks_protocol_) {
1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    sync_pb::SyncEntity_BookmarkData* data = entity->mutable_bookmarkdata();
1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    data->set_bookmark_folder(is_folder);
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!is_folder) {
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      data->set_bookmark_url("http://google.com");
1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {
1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    entity->set_folder(is_folder);
1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    entity->mutable_specifics()->mutable_bookmark();
1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!is_folder) {
1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      entity->mutable_specifics()->mutable_bookmark()->
1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          set_url("http://google.com");
1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)sync_pb::SyncEntity* MockConnectionManager::AddUpdateDirectory(
2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int id,
2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int parent_id,
2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    string name,
2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int64 version,
2062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    int64 sync_ts,
2072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    std::string originator_cache_guid,
2082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    std::string originator_client_item_id) {
2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return AddUpdateDirectory(TestIdFactory::FromNumber(id),
2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            TestIdFactory::FromNumber(parent_id),
2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            name,
2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            version,
2132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                            sync_ts,
2142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                            originator_cache_guid,
2152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                            originator_client_item_id);
2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void MockConnectionManager::SetGUClientCommand(
2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    sync_pb::ClientCommand* command) {
2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  gu_client_command_.reset(command);
2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void MockConnectionManager::SetCommitClientCommand(
2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    sync_pb::ClientCommand* command) {
2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  commit_client_command_.reset(command);
2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void MockConnectionManager::SetTransientErrorId(syncable::Id id) {
2292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  transient_error_ids_.push_back(id);
2302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)sync_pb::SyncEntity* MockConnectionManager::AddUpdateBookmark(
2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int id, int parent_id,
2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    string name, int64 version,
2352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    int64 sync_ts,
2362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    string originator_client_item_id,
2372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    string originator_cache_guid) {
2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return AddUpdateBookmark(TestIdFactory::FromNumber(id),
2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                           TestIdFactory::FromNumber(parent_id),
2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                           name,
2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                           version,
2422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                           sync_ts,
2432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                           originator_client_item_id,
2442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                           originator_cache_guid);
2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)sync_pb::SyncEntity* MockConnectionManager::AddUpdateSpecifics(
2482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    int id,
2492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    int parent_id,
2502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    string name,
2512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    int64 version,
2522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    int64 sync_ts,
2532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    bool is_dir,
2542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    int64 position,
2552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const sync_pb::EntitySpecifics& specifics) {
2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  sync_pb::SyncEntity* ent = AddUpdateMeta(
2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      TestIdFactory::FromNumber(id).GetServerId(),
2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      TestIdFactory::FromNumber(parent_id).GetServerId(),
2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      name, version, sync_ts);
2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ent->set_position_in_parent(position);
2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ent->mutable_specifics()->CopyFrom(specifics);
2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ent->set_folder(is_dir);
2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return ent;
2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)sync_pb::SyncEntity* MockConnectionManager::AddUpdateSpecifics(
2672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    int id,
2682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    int parent_id,
2692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    string name,
2702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    int64 version,
2712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    int64 sync_ts,
2722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    bool is_dir,
2732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    int64 position,
2742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const sync_pb::EntitySpecifics& specifics,
2752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    string originator_cache_guid,
2762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    string originator_client_item_id) {
2772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  sync_pb::SyncEntity* ent = AddUpdateSpecifics(
2782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      id, parent_id, name, version, sync_ts, is_dir, position, specifics);
2792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ent->set_originator_cache_guid(originator_cache_guid);
2802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ent->set_originator_client_item_id(originator_client_item_id);
2812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return ent;
2822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)sync_pb::SyncEntity* MockConnectionManager::SetNigori(
2852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    int id,
2862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    int64 version,
2872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    int64 sync_ts,
2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const sync_pb::EntitySpecifics& specifics) {
2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  sync_pb::SyncEntity* ent = GetUpdateResponse()->add_entries();
2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ent->set_id_string(TestIdFactory::FromNumber(id).GetServerId());
2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ent->set_parent_id_string(TestIdFactory::FromNumber(0).GetServerId());
2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ent->set_server_defined_unique_tag(ModelTypeToRootTag(NIGORI));
2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ent->set_name("Nigori");
2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ent->set_non_unique_name("Nigori");
2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ent->set_version(version);
2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ent->set_sync_timestamp(sync_ts);
2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ent->set_mtime(sync_ts);
2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ent->set_ctime(1);
2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ent->set_position_in_parent(0);
3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ent->set_folder(false);
3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ent->mutable_specifics()->CopyFrom(specifics);
3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return ent;
3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)sync_pb::SyncEntity* MockConnectionManager::AddUpdatePref(string id,
3062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                                          string parent_id,
3072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                                          string client_tag,
3082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                                          int64 version,
3092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                                          int64 sync_ts) {
3102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  sync_pb::SyncEntity* ent =
3112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      AddUpdateMeta(id, parent_id, " ", version, sync_ts);
3122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ent->set_client_defined_unique_tag(client_tag);
3142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  sync_pb::EntitySpecifics specifics;
3162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  AddDefaultFieldValue(PREFERENCES, &specifics);
3172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ent->mutable_specifics()->CopyFrom(specifics);
3182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return ent;
3202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)sync_pb::SyncEntity* MockConnectionManager::AddUpdateFull(
3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    string id, string parent_id,
3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    string name, int64 version,
3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int64 sync_ts, bool is_dir) {
3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  sync_pb::SyncEntity* ent =
3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      AddUpdateMeta(id, parent_id, name, version, sync_ts);
3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  AddDefaultBookmarkData(ent, is_dir);
3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return ent;
3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)sync_pb::SyncEntity* MockConnectionManager::AddUpdateMeta(
3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    string id, string parent_id,
3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    string name, int64 version,
3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int64 sync_ts) {
3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  sync_pb::SyncEntity* ent = GetUpdateResponse()->add_entries();
3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ent->set_id_string(id);
3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ent->set_parent_id_string(parent_id);
3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ent->set_non_unique_name(name);
3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ent->set_name(name);
3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ent->set_version(version);
3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ent->set_sync_timestamp(sync_ts);
3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ent->set_mtime(sync_ts);
3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ent->set_ctime(1);
3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ent->set_position_in_parent(GeneratePositionInParent());
3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return ent;
3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)sync_pb::SyncEntity* MockConnectionManager::AddUpdateDirectory(
3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    string id,
3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    string parent_id,
3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    string name,
3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int64 version,
3542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    int64 sync_ts,
3552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    std::string originator_cache_guid,
3562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    std::string originator_client_item_id) {
3572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  sync_pb::SyncEntity* ret =
3582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      AddUpdateFull(id, parent_id, name, version, sync_ts, true);
3592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ret->set_originator_cache_guid(originator_cache_guid);
3602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ret->set_originator_client_item_id(originator_client_item_id);
3612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return ret;
3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)sync_pb::SyncEntity* MockConnectionManager::AddUpdateBookmark(
3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    string id,
3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    string parent_id,
3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    string name, int64 version,
3682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    int64 sync_ts,
3692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    string originator_cache_guid,
3702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    string originator_client_item_id) {
3712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  sync_pb::SyncEntity* ret =
3722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      AddUpdateFull(id, parent_id, name, version, sync_ts, false);
3732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ret->set_originator_cache_guid(originator_cache_guid);
3742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ret->set_originator_client_item_id(originator_client_item_id);
3752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return ret;
3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)sync_pb::SyncEntity* MockConnectionManager::AddUpdateFromLastCommit() {
3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(1, last_sent_commit().entries_size());
3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(1, last_commit_response().entryresponse_size());
3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(CommitResponse::SUCCESS,
3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      last_commit_response().entryresponse(0).response_type());
3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (last_sent_commit().entries(0).deleted()) {
3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    AddUpdateTombstone(syncable::Id::CreateFromServerId(
3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        last_sent_commit().entries(0).id_string()));
3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {
3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    sync_pb::SyncEntity* ent = GetUpdateResponse()->add_entries();
3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ent->CopyFrom(last_sent_commit().entries(0));
3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ent->clear_insert_after_item_id();
3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ent->clear_old_parent_id();
3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ent->set_position_in_parent(
3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        last_commit_response().entryresponse(0).position_in_parent());
3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ent->set_version(
3955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        last_commit_response().entryresponse(0).version());
3965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ent->set_id_string(
3975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        last_commit_response().entryresponse(0).id_string());
3985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Tests don't currently care about the following:
3995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // originator_cache_guid, originator_client_item_id, parent_id_string,
4005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // name, non_unique_name.
4015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return GetMutableLastUpdate();
4035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void MockConnectionManager::AddUpdateTombstone(const syncable::Id& id) {
4065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Tombstones have only the ID set and dummy values for the required fields.
4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  sync_pb::SyncEntity* ent = GetUpdateResponse()->add_entries();
4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ent->set_id_string(id.GetServerId());
4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ent->set_version(0);
4105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ent->set_name("");
4115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ent->set_deleted(true);
4125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void MockConnectionManager::SetLastUpdateDeleted() {
4155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Tombstones have only the ID set.  Wipe anything else.
4165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  string id_string = GetMutableLastUpdate()->id_string();
4175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GetUpdateResponse()->mutable_entries()->RemoveLast();
4185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  AddUpdateTombstone(syncable::Id::CreateFromServerId(id_string));
4195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void MockConnectionManager::SetLastUpdateOriginatorFields(
4225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const string& client_id,
4235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const string& entry_id) {
4245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GetMutableLastUpdate()->set_originator_cache_guid(client_id);
4255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GetMutableLastUpdate()->set_originator_client_item_id(entry_id);
4265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void MockConnectionManager::SetLastUpdateServerTag(const string& tag) {
4295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GetMutableLastUpdate()->set_server_defined_unique_tag(tag);
4305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void MockConnectionManager::SetLastUpdateClientTag(const string& tag) {
4335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GetMutableLastUpdate()->set_client_defined_unique_tag(tag);
4345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void MockConnectionManager::SetLastUpdatePosition(int64 server_position) {
4375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GetMutableLastUpdate()->set_position_in_parent(server_position);
4385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void MockConnectionManager::SetNewTimestamp(int ts) {
4415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  next_token_ = base::StringPrintf("mock connection ts = %d", ts);
4425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ApplyToken();
4435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void MockConnectionManager::ApplyToken() {
4465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!update_queue_.empty()) {
4475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    GetUpdateResponse()->clear_new_progress_marker();
4485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    sync_pb::DataTypeProgressMarker* new_marker =
4495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        GetUpdateResponse()->add_new_progress_marker();
4505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    new_marker->set_data_type_id(-1);  // Invalid -- clients shouldn't see.
4515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    new_marker->set_token(next_token_);
4525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void MockConnectionManager::SetChangesRemaining(int64 timestamp) {
4565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GetUpdateResponse()->set_changes_remaining(timestamp);
4575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void MockConnectionManager::ProcessGetUpdates(
4605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    sync_pb::ClientToServerMessage* csm,
4615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    sync_pb::ClientToServerResponse* response) {
4625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CHECK(csm->has_get_updates());
4635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(csm->message_contents(), ClientToServerMessage::GET_UPDATES);
4645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GetUpdatesMessage& gu = csm->get_updates();
4655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  num_get_updates_requests_++;
4665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(gu.has_from_timestamp());
4675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(gu.has_requested_types());
4685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (fail_non_periodic_get_updates_) {
4705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(sync_pb::GetUpdatesCallerInfo::PERIODIC,
4715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              gu.caller_info().source());
4725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Verify that the GetUpdates filter sent by the Syncer matches the test
4755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // expectation.
4762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ModelTypeSet protocol_types = ProtocolTypes();
4772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  for (ModelTypeSet::Iterator iter = protocol_types.First(); iter.Good();
4782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)       iter.Inc()) {
4792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ModelType model_type = iter.Get();
4805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    sync_pb::DataTypeProgressMarker const* progress_marker =
4815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        GetProgressMarkerForType(gu.from_progress_marker(), model_type);
4825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(expected_filter_.Has(model_type), (progress_marker != NULL))
4835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        << "Syncer requested_types differs from test expectation.";
4845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (progress_marker) {
4855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      EXPECT_EQ((expected_states_.count(model_type) > 0 ?
4865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 expected_states_[model_type].payload :
4875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 std::string()),
4885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                progress_marker->notification_hint());
4895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
4905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Verify that the items we're about to send back to the client are of
4935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // the types requested by the client.  If this fails, it probably indicates
4945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // a test bug.
4955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(gu.fetch_folders());
4965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(gu.has_requested_types());
4975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (update_queue_.empty()) {
4985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    GetUpdateResponse();
4995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  sync_pb::GetUpdatesResponse* updates = &update_queue_.front();
5015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (int i = 0; i < updates->entries_size(); ++i) {
5025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!updates->entries(i).deleted()) {
5035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ModelType entry_type = GetModelType(updates->entries(i));
5045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      EXPECT_TRUE(
5055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          IsModelTypePresentInSpecifics(gu.from_progress_marker(), entry_type))
5065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          << "Syncer did not request updates being provided by the test.";
5075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
5085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  response->mutable_get_updates()->CopyFrom(*updates);
5115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Set appropriate progress markers, overriding the value squirreled
5135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // away by ApplyToken().
5145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string token = response->get_updates().new_progress_marker(0).token();
5155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  response->mutable_get_updates()->clear_new_progress_marker();
5165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (int i = 0; i < gu.from_progress_marker_size(); ++i) {
5175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (gu.from_progress_marker(i).token() != token) {
5185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      sync_pb::DataTypeProgressMarker* new_marker =
5195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          response->mutable_get_updates()->add_new_progress_marker();
5205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      new_marker->set_data_type_id(gu.from_progress_marker(i).data_type_id());
5215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      new_marker->set_token(token);
5225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
5235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Fill the keystore key if requested.
5265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (gu.need_encryption_key())
5272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    response->mutable_get_updates()->add_encryption_keys(keystore_key_);
5285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  update_queue_.pop_front();
5305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (gu_client_command_.get()) {
5325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    response->mutable_client_command()->CopyFrom(*gu_client_command_.get());
5335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void MockConnectionManager::SetKeystoreKey(const std::string& key) {
5375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Note: this is not a thread-safe set, ok for now.  NOT ok if tests
5385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // run the syncer on the background thread while this method is called.
5395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  keystore_key_ = key;
5405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool MockConnectionManager::ShouldConflictThisCommit() {
5435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool conflict = false;
5445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (conflict_all_commits_) {
5455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    conflict = true;
5465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else if (conflict_n_commits_ > 0) {
5475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    conflict = true;
5485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    --conflict_n_commits_;
5495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return conflict;
5515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool MockConnectionManager::ShouldTransientErrorThisId(syncable::Id id) {
5542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return find(transient_error_ids_.begin(), transient_error_ids_.end(), id)
5552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      != transient_error_ids_.end();
5562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
5572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void MockConnectionManager::ProcessCommit(
5595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    sync_pb::ClientToServerMessage* csm,
5605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    sync_pb::ClientToServerResponse* response_buffer) {
5615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CHECK(csm->has_commit());
5625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(csm->message_contents(), ClientToServerMessage::COMMIT);
5635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  map <string, string> changed_ids;
5645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const CommitMessage& commit_message = csm->commit();
5655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CommitResponse* commit_response = response_buffer->mutable_commit();
5665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  commit_messages_.push_back(new CommitMessage);
5675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  commit_messages_.back()->CopyFrom(commit_message);
5685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  map<string, sync_pb::CommitResponse_EntryResponse*> response_map;
5695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (int i = 0; i < commit_message.entries_size() ; i++) {
5705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const sync_pb::SyncEntity& entry = commit_message.entries(i);
5715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CHECK(entry.has_id_string());
5722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    string id_string = entry.id_string();
5735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_LT(entry.name().length(), 256ul) << " name probably too long. True "
5745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        "server name checking not implemented";
5752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    syncable::Id id;
5765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (entry.version() == 0) {
5775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // Relies on our new item string id format. (string representation of a
5785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // negative number).
5792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      id = syncable::Id::CreateFromClientString(id_string);
5805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else {
5812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      id = syncable::Id::CreateFromServerId(id_string);
5825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
5832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    committed_ids_.push_back(id);
5842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (response_map.end() == response_map.find(id_string))
5862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      response_map[id_string] = commit_response->add_entryresponse();
5872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    sync_pb::CommitResponse_EntryResponse* er = response_map[id_string];
5885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (ShouldConflictThisCommit()) {
5895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      er->set_response_type(CommitResponse::CONFLICT);
5905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      continue;
5915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
5922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (ShouldTransientErrorThisId(id)) {
5932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      er->set_response_type(CommitResponse::TRANSIENT_ERROR);
5942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      continue;
5952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
5965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    er->set_response_type(CommitResponse::SUCCESS);
5975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    er->set_version(entry.version() + 1);
5985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!commit_time_rename_prepended_string_.empty()) {
5995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // Commit time rename sent down from the server.
6005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      er->set_name(commit_time_rename_prepended_string_ + entry.name());
6015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
6022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    string parent_id_string = entry.parent_id_string();
6035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Remap id's we've already assigned.
6042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (changed_ids.end() != changed_ids.find(parent_id_string)) {
6052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      parent_id_string = changed_ids[parent_id_string];
6062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      er->set_parent_id_string(parent_id_string);
6075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
6085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (entry.has_version() && 0 != entry.version()) {
6092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      er->set_id_string(id_string);  // Allows verification.
6105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else {
6115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      string new_id = base::StringPrintf("mock_server:%d", next_new_id_++);
6122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      changed_ids[id_string] = new_id;
6135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      er->set_id_string(new_id);
6145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
6155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
6165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  commit_responses_.push_back(new CommitResponse(*commit_response));
6175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (commit_client_command_.get()) {
6195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    response_buffer->mutable_client_command()->CopyFrom(
6205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        *commit_client_command_.get());
6215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
6225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)sync_pb::SyncEntity* MockConnectionManager::AddUpdateDirectory(
6252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    syncable::Id id,
6262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    syncable::Id parent_id,
6272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    string name,
6282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    int64 version,
6292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    int64 sync_ts,
6302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    string originator_cache_guid,
6312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    string originator_client_item_id) {
6325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return AddUpdateDirectory(id.GetServerId(), parent_id.GetServerId(),
6332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                            name, version, sync_ts, originator_cache_guid,
6342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                            originator_client_item_id);
6355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)sync_pb::SyncEntity* MockConnectionManager::AddUpdateBookmark(
6382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    syncable::Id id,
6392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    syncable::Id parent_id,
6402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    string name,
6412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    int64 version,
6422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    int64 sync_ts,
6432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    string originator_cache_guid,
6442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    string originator_client_item_id) {
6455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return AddUpdateBookmark(id.GetServerId(), parent_id.GetServerId(),
6462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                           name, version, sync_ts, originator_cache_guid,
6472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                           originator_client_item_id);
6485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)sync_pb::SyncEntity* MockConnectionManager::GetMutableLastUpdate() {
6515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  sync_pb::GetUpdatesResponse* updates = GetUpdateResponse();
6525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_GT(updates->entries_size(), 0);
6535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return updates->mutable_entries()->Mutable(updates->entries_size() - 1);
6545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void MockConnectionManager::NextUpdateBatch() {
6575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  update_queue_.push_back(sync_pb::GetUpdatesResponse::default_instance());
6585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SetChangesRemaining(0);
6595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ApplyToken();
6605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const CommitMessage& MockConnectionManager::last_sent_commit() const {
6635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(!commit_messages_.empty());
6645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return *commit_messages_.back();
6655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const CommitResponse& MockConnectionManager::last_commit_response() const {
6685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(!commit_responses_.empty());
6695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return *commit_responses_.back();
6705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool MockConnectionManager::IsModelTypePresentInSpecifics(
6735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const google::protobuf::RepeatedPtrField<
6745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        sync_pb::DataTypeProgressMarker>& filter,
6755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ModelType value) {
6765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int data_type_id = GetSpecificsFieldNumberFromModelType(value);
6775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (int i = 0; i < filter.size(); ++i) {
6785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (filter.Get(i).data_type_id() == data_type_id) {
6795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return true;
6805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
6815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
6825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return false;
6835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)sync_pb::DataTypeProgressMarker const*
6865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockConnectionManager::GetProgressMarkerForType(
6875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        const google::protobuf::RepeatedPtrField<
6885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            sync_pb::DataTypeProgressMarker>& filter,
6895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        ModelType value) {
6905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int data_type_id = GetSpecificsFieldNumberFromModelType(value);
6915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (int i = 0; i < filter.size(); ++i) {
6925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (filter.Get(i).data_type_id() == data_type_id) {
6935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return &(filter.Get(i));
6945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
6955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
6965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return NULL;
6975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void MockConnectionManager::SetServerReachable() {
7005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  server_reachable_ = true;
7015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void MockConnectionManager::SetServerNotReachable() {
7045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  server_reachable_ = false;
7055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void MockConnectionManager::UpdateConnectionStatus() {
7085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!server_reachable_) {
7095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    server_status_ = HttpResponse::CONNECTION_UNAVAILABLE;
7105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {
7115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    server_status_ = HttpResponse::SERVER_CONNECTION_OK;
7125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
7135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace syncer
716