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