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