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 9namespace syncer { 10 11MockModelTypeSyncProxy::MockModelTypeSyncProxy() : is_synchronous_(true) { 12} 13 14MockModelTypeSyncProxy::~MockModelTypeSyncProxy() { 15} 16 17void 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 30void 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 44void MockModelTypeSyncProxy::SetSynchronousExecution(bool is_synchronous) { 45 is_synchronous_ = is_synchronous; 46} 47 48void 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 57CommitRequestData 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 83CommitRequestData 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 106size_t MockModelTypeSyncProxy::GetNumUpdateResponses() const { 107 return received_update_responses_.size(); 108} 109 110UpdateResponseDataList MockModelTypeSyncProxy::GetNthUpdateResponse( 111 size_t n) const { 112 DCHECK_LT(n, GetNumUpdateResponses()); 113 return received_update_responses_[n]; 114} 115 116UpdateResponseDataList MockModelTypeSyncProxy::GetNthPendingUpdates( 117 size_t n) const { 118 DCHECK_LT(n, GetNumUpdateResponses()); 119 return received_pending_updates_[n]; 120} 121 122DataTypeState MockModelTypeSyncProxy::GetNthTypeStateReceivedInUpdateResponse( 123 size_t n) const { 124 DCHECK_LT(n, GetNumUpdateResponses()); 125 return type_states_received_on_update_[n]; 126} 127 128size_t MockModelTypeSyncProxy::GetNumCommitResponses() const { 129 return received_commit_responses_.size(); 130} 131 132CommitResponseDataList MockModelTypeSyncProxy::GetNthCommitResponse( 133 size_t n) const { 134 DCHECK_LT(n, GetNumCommitResponses()); 135 return received_commit_responses_[n]; 136} 137 138DataTypeState MockModelTypeSyncProxy::GetNthTypeStateReceivedInCommitResponse( 139 size_t n) const { 140 DCHECK_LT(n, GetNumCommitResponses()); 141 return type_states_received_on_commit_[n]; 142} 143 144bool 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 151UpdateResponseData 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 159bool 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 166CommitResponseData 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 174void 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 190void 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. 209int64 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. 222int64 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 230int64 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 241void MockModelTypeSyncProxy::SetBaseVersion(const std::string& tag_hash, 242 int64 version) { 243 base_versions_[tag_hash] = version; 244} 245 246bool MockModelTypeSyncProxy::HasServerAssignedId( 247 const std::string& tag_hash) const { 248 return assigned_ids_.find(tag_hash) != assigned_ids_.end(); 249} 250 251const 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 257void MockModelTypeSyncProxy::SetServerAssignedId(const std::string& tag_hash, 258 const std::string& id) { 259 assigned_ids_[tag_hash] = id; 260} 261 262} // namespace syncer 263