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