Home | History | Annotate | Download | only in engine
      1 // Copyright 2014 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #include "sync/test/engine/mock_model_type_sync_proxy.h"
      6 
      7 #include "base/bind.h"
      8 
      9 namespace syncer {
     10 
     11 MockModelTypeSyncProxy::MockModelTypeSyncProxy() : is_synchronous_(true) {
     12 }
     13 
     14 MockModelTypeSyncProxy::~MockModelTypeSyncProxy() {
     15 }
     16 
     17 void MockModelTypeSyncProxy::OnCommitCompleted(
     18     const DataTypeState& type_state,
     19     const CommitResponseDataList& response_list) {
     20   base::Closure task =
     21       base::Bind(&MockModelTypeSyncProxy::OnCommitCompletedImpl,
     22                  base::Unretained(this),
     23                  type_state,
     24                  response_list);
     25   pending_tasks_.push_back(task);
     26   if (is_synchronous_)
     27     RunQueuedTasks();
     28 }
     29 
     30 void MockModelTypeSyncProxy::OnUpdateReceived(
     31     const DataTypeState& type_state,
     32     const UpdateResponseDataList& response_list,
     33     const UpdateResponseDataList& pending_updates) {
     34   base::Closure task = base::Bind(&MockModelTypeSyncProxy::OnUpdateReceivedImpl,
     35                                   base::Unretained(this),
     36                                   type_state,
     37                                   response_list,
     38                                   pending_updates);
     39   pending_tasks_.push_back(task);
     40   if (is_synchronous_)
     41     RunQueuedTasks();
     42 }
     43 
     44 void MockModelTypeSyncProxy::SetSynchronousExecution(bool is_synchronous) {
     45   is_synchronous_ = is_synchronous;
     46 }
     47 
     48 void MockModelTypeSyncProxy::RunQueuedTasks() {
     49   for (std::vector<base::Closure>::iterator it = pending_tasks_.begin();
     50        it != pending_tasks_.end();
     51        ++it) {
     52     it->Run();
     53   }
     54   pending_tasks_.clear();
     55 }
     56 
     57 CommitRequestData MockModelTypeSyncProxy::CommitRequest(
     58     const std::string& tag_hash,
     59     const sync_pb::EntitySpecifics& specifics) {
     60   const int64 base_version = GetBaseVersion(tag_hash);
     61 
     62   CommitRequestData data;
     63 
     64   if (HasServerAssignedId(tag_hash)) {
     65     data.id = GetServerAssignedId(tag_hash);
     66   }
     67 
     68   data.client_tag_hash = tag_hash;
     69   data.sequence_number = GetNextSequenceNumber(tag_hash);
     70   data.deleted = false;
     71   data.specifics = specifics;
     72   data.base_version = base_version;
     73 
     74   // These fields are not really used for much, but we set them anyway
     75   // to make this item look more realistic.
     76   data.ctime = base::Time::UnixEpoch() + base::TimeDelta::FromDays(1);
     77   data.mtime = data.ctime + base::TimeDelta::FromSeconds(base_version);
     78   data.non_unique_name = "Name: " + tag_hash;
     79 
     80   return data;
     81 }
     82 
     83 CommitRequestData MockModelTypeSyncProxy::DeleteRequest(
     84     const std::string& tag_hash) {
     85   const int64 base_version = GetBaseVersion(tag_hash);
     86   CommitRequestData data;
     87 
     88   if (HasServerAssignedId(tag_hash)) {
     89     data.id = GetServerAssignedId(tag_hash);
     90   }
     91 
     92   data.client_tag_hash = tag_hash;
     93   data.sequence_number = GetNextSequenceNumber(tag_hash);
     94   data.base_version = base_version;
     95   data.mtime = data.ctime + base::TimeDelta::FromSeconds(base_version);
     96   data.deleted = true;
     97 
     98   // These fields have little or no effect on behavior.  We set them anyway to
     99   // make the test more realistic.
    100   data.ctime = base::Time::UnixEpoch() + base::TimeDelta::FromDays(1);
    101   data.non_unique_name = "Name deleted";
    102 
    103   return data;
    104 }
    105 
    106 size_t MockModelTypeSyncProxy::GetNumUpdateResponses() const {
    107   return received_update_responses_.size();
    108 }
    109 
    110 UpdateResponseDataList MockModelTypeSyncProxy::GetNthUpdateResponse(
    111     size_t n) const {
    112   DCHECK_LT(n, GetNumUpdateResponses());
    113   return received_update_responses_[n];
    114 }
    115 
    116 UpdateResponseDataList MockModelTypeSyncProxy::GetNthPendingUpdates(
    117     size_t n) const {
    118   DCHECK_LT(n, GetNumUpdateResponses());
    119   return received_pending_updates_[n];
    120 }
    121 
    122 DataTypeState MockModelTypeSyncProxy::GetNthTypeStateReceivedInUpdateResponse(
    123     size_t n) const {
    124   DCHECK_LT(n, GetNumUpdateResponses());
    125   return type_states_received_on_update_[n];
    126 }
    127 
    128 size_t MockModelTypeSyncProxy::GetNumCommitResponses() const {
    129   return received_commit_responses_.size();
    130 }
    131 
    132 CommitResponseDataList MockModelTypeSyncProxy::GetNthCommitResponse(
    133     size_t n) const {
    134   DCHECK_LT(n, GetNumCommitResponses());
    135   return received_commit_responses_[n];
    136 }
    137 
    138 DataTypeState MockModelTypeSyncProxy::GetNthTypeStateReceivedInCommitResponse(
    139     size_t n) const {
    140   DCHECK_LT(n, GetNumCommitResponses());
    141   return type_states_received_on_commit_[n];
    142 }
    143 
    144 bool MockModelTypeSyncProxy::HasUpdateResponse(
    145     const std::string& tag_hash) const {
    146   std::map<const std::string, UpdateResponseData>::const_iterator it =
    147       update_response_items_.find(tag_hash);
    148   return it != update_response_items_.end();
    149 }
    150 
    151 UpdateResponseData MockModelTypeSyncProxy::GetUpdateResponse(
    152     const std::string& tag_hash) const {
    153   DCHECK(HasUpdateResponse(tag_hash));
    154   std::map<const std::string, UpdateResponseData>::const_iterator it =
    155       update_response_items_.find(tag_hash);
    156   return it->second;
    157 }
    158 
    159 bool MockModelTypeSyncProxy::HasCommitResponse(
    160     const std::string& tag_hash) const {
    161   std::map<const std::string, CommitResponseData>::const_iterator it =
    162       commit_response_items_.find(tag_hash);
    163   return it != commit_response_items_.end();
    164 }
    165 
    166 CommitResponseData MockModelTypeSyncProxy::GetCommitResponse(
    167     const std::string& tag_hash) const {
    168   DCHECK(HasCommitResponse(tag_hash));
    169   std::map<const std::string, CommitResponseData>::const_iterator it =
    170       commit_response_items_.find(tag_hash);
    171   return it->second;
    172 }
    173 
    174 void MockModelTypeSyncProxy::OnCommitCompletedImpl(
    175     const DataTypeState& type_state,
    176     const CommitResponseDataList& response_list) {
    177   received_commit_responses_.push_back(response_list);
    178   type_states_received_on_commit_.push_back(type_state);
    179   for (CommitResponseDataList::const_iterator it = response_list.begin();
    180        it != response_list.end();
    181        ++it) {
    182     commit_response_items_.insert(std::make_pair(it->client_tag_hash, *it));
    183 
    184     // Server wins.  Set the model's base version.
    185     SetBaseVersion(it->client_tag_hash, it->response_version);
    186     SetServerAssignedId(it->client_tag_hash, it->id);
    187   }
    188 }
    189 
    190 void MockModelTypeSyncProxy::OnUpdateReceivedImpl(
    191     const DataTypeState& type_state,
    192     const UpdateResponseDataList& response_list,
    193     const UpdateResponseDataList& pending_updates) {
    194   received_update_responses_.push_back(response_list);
    195   received_pending_updates_.push_back(pending_updates);
    196   type_states_received_on_update_.push_back(type_state);
    197   for (UpdateResponseDataList::const_iterator it = response_list.begin();
    198        it != response_list.end();
    199        ++it) {
    200     update_response_items_.insert(std::make_pair(it->client_tag_hash, *it));
    201 
    202     // Server wins.  Set the model's base version.
    203     SetBaseVersion(it->client_tag_hash, it->response_version);
    204     SetServerAssignedId(it->client_tag_hash, it->id);
    205   }
    206 }
    207 
    208 // Fetches the sequence number as of the most recent update request.
    209 int64 MockModelTypeSyncProxy::GetCurrentSequenceNumber(
    210     const std::string& tag_hash) const {
    211   std::map<const std::string, int64>::const_iterator it =
    212       sequence_numbers_.find(tag_hash);
    213   if (it == sequence_numbers_.end()) {
    214     return 0;
    215   } else {
    216     return it->second;
    217   }
    218 }
    219 
    220 // The model thread should be sending us items with strictly increasing
    221 // sequence numbers.  Here's where we emulate that behavior.
    222 int64 MockModelTypeSyncProxy::GetNextSequenceNumber(
    223     const std::string& tag_hash) {
    224   int64 sequence_number = GetCurrentSequenceNumber(tag_hash);
    225   sequence_number++;
    226   sequence_numbers_[tag_hash] = sequence_number;
    227   return sequence_number;
    228 }
    229 
    230 int64 MockModelTypeSyncProxy::GetBaseVersion(
    231     const std::string& tag_hash) const {
    232   std::map<const std::string, int64>::const_iterator it =
    233       base_versions_.find(tag_hash);
    234   if (it == base_versions_.end()) {
    235     return kUncommittedVersion;
    236   } else {
    237     return it->second;
    238   }
    239 }
    240 
    241 void MockModelTypeSyncProxy::SetBaseVersion(const std::string& tag_hash,
    242                                             int64 version) {
    243   base_versions_[tag_hash] = version;
    244 }
    245 
    246 bool MockModelTypeSyncProxy::HasServerAssignedId(
    247     const std::string& tag_hash) const {
    248   return assigned_ids_.find(tag_hash) != assigned_ids_.end();
    249 }
    250 
    251 const std::string& MockModelTypeSyncProxy::GetServerAssignedId(
    252     const std::string& tag_hash) const {
    253   DCHECK(HasServerAssignedId(tag_hash));
    254   return assigned_ids_.find(tag_hash)->second;
    255 }
    256 
    257 void MockModelTypeSyncProxy::SetServerAssignedId(const std::string& tag_hash,
    258                                                  const std::string& id) {
    259   assigned_ids_[tag_hash] = id;
    260 }
    261 
    262 }  // namespace syncer
    263