OLD | NEW |
| (Empty) |
1 // Copyright (c) 2012 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 // Mock ServerConnectionManager class for use in client regression tests. | |
6 | |
7 #include "chrome/browser/sync/test/engine/mock_connection_manager.h" | |
8 | |
9 #include <map> | |
10 | |
11 #include "base/location.h" | |
12 #include "base/stringprintf.h" | |
13 #include "chrome/browser/sync/engine/syncer_proto_util.h" | |
14 #include "chrome/browser/sync/test/engine/test_id_factory.h" | |
15 #include "sync/protocol/bookmark_specifics.pb.h" | |
16 #include "testing/gtest/include/gtest/gtest.h" | |
17 | |
18 using browser_sync::HttpResponse; | |
19 using browser_sync::ServerConnectionManager; | |
20 using browser_sync::ServerConnectionEventListener; | |
21 using browser_sync::ServerConnectionEvent; | |
22 using browser_sync::SyncerProtoUtil; | |
23 using browser_sync::TestIdFactory; | |
24 using std::map; | |
25 using std::string; | |
26 using sync_pb::ClientToServerMessage; | |
27 using sync_pb::ClientToServerResponse; | |
28 using sync_pb::CommitMessage; | |
29 using sync_pb::CommitResponse; | |
30 using sync_pb::CommitResponse_EntryResponse; | |
31 using sync_pb::GetUpdatesMessage; | |
32 using sync_pb::SyncEnums; | |
33 using sync_pb::SyncEntity; | |
34 using syncable::FIRST_REAL_MODEL_TYPE; | |
35 using syncable::MODEL_TYPE_COUNT; | |
36 using syncable::ModelType; | |
37 using syncable::WriteTransaction; | |
38 | |
39 MockConnectionManager::MockConnectionManager(syncable::Directory* directory) | |
40 : ServerConnectionManager("unused", 0, false, "version"), | |
41 conflict_all_commits_(false), | |
42 conflict_n_commits_(0), | |
43 next_new_id_(10000), | |
44 store_birthday_("Store BDay!"), | |
45 store_birthday_sent_(false), | |
46 client_stuck_(false), | |
47 commit_time_rename_prepended_string_(""), | |
48 fail_next_postbuffer_(false), | |
49 directory_(directory), | |
50 mid_commit_observer_(NULL), | |
51 throttling_(false), | |
52 fail_with_auth_invalid_(false), | |
53 fail_non_periodic_get_updates_(false), | |
54 client_command_(NULL), | |
55 next_position_in_parent_(2), | |
56 use_legacy_bookmarks_protocol_(false), | |
57 num_get_updates_requests_(0) { | |
58 server_reachable_ = true; | |
59 SetNewTimestamp(0); | |
60 } | |
61 | |
62 MockConnectionManager::~MockConnectionManager() { | |
63 EXPECT_TRUE(update_queue_.empty()) << "Unfetched updates."; | |
64 } | |
65 | |
66 void MockConnectionManager::SetCommitTimeRename(string prepend) { | |
67 commit_time_rename_prepended_string_ = prepend; | |
68 } | |
69 | |
70 void MockConnectionManager::SetMidCommitCallback( | |
71 const base::Closure& callback) { | |
72 mid_commit_callback_ = callback; | |
73 } | |
74 | |
75 void MockConnectionManager::SetMidCommitObserver( | |
76 MockConnectionManager::MidCommitObserver* observer) { | |
77 mid_commit_observer_ = observer; | |
78 } | |
79 | |
80 bool MockConnectionManager::PostBufferToPath(PostBufferParams* params, | |
81 const string& path, | |
82 const string& auth_token, | |
83 browser_sync::ScopedServerStatusWatcher* watcher) { | |
84 ClientToServerMessage post; | |
85 CHECK(post.ParseFromString(params->buffer_in)); | |
86 last_request_.CopyFrom(post); | |
87 client_stuck_ = post.sync_problem_detected(); | |
88 ClientToServerResponse response; | |
89 response.Clear(); | |
90 | |
91 if (directory_) { | |
92 // If the Directory's locked when we do this, it's a problem as in normal | |
93 // use this function could take a while to return because it accesses the | |
94 // network. As we can't test this we do the next best thing and hang here | |
95 // when there's an issue. | |
96 CHECK(directory_->good()); | |
97 WriteTransaction wt(FROM_HERE, syncable::UNITTEST, directory_); | |
98 } | |
99 | |
100 if (fail_next_postbuffer_) { | |
101 fail_next_postbuffer_ = false; | |
102 return false; | |
103 } | |
104 | |
105 if (!server_reachable_) { | |
106 params->response.server_status = HttpResponse::CONNECTION_UNAVAILABLE; | |
107 return false; | |
108 } | |
109 | |
110 // Default to an ok connection. | |
111 params->response.server_status = HttpResponse::SERVER_CONNECTION_OK; | |
112 response.set_error_code(SyncEnums::SUCCESS); | |
113 const string current_store_birthday = store_birthday(); | |
114 response.set_store_birthday(current_store_birthday); | |
115 if (post.has_store_birthday() && post.store_birthday() != | |
116 current_store_birthday) { | |
117 response.set_error_code(SyncEnums::NOT_MY_BIRTHDAY); | |
118 response.set_error_message("Merry Unbirthday!"); | |
119 response.SerializeToString(¶ms->buffer_out); | |
120 store_birthday_sent_ = true; | |
121 return true; | |
122 } | |
123 bool result = true; | |
124 EXPECT_TRUE(!store_birthday_sent_ || post.has_store_birthday() || | |
125 post.message_contents() == ClientToServerMessage::AUTHENTICATE); | |
126 store_birthday_sent_ = true; | |
127 | |
128 if (post.message_contents() == ClientToServerMessage::COMMIT) { | |
129 ProcessCommit(&post, &response); | |
130 } else if (post.message_contents() == ClientToServerMessage::GET_UPDATES) { | |
131 ProcessGetUpdates(&post, &response); | |
132 } else if (post.message_contents() == ClientToServerMessage::AUTHENTICATE) { | |
133 ProcessAuthenticate(&post, &response, auth_token); | |
134 } else if (post.message_contents() == ClientToServerMessage::CLEAR_DATA) { | |
135 ProcessClearData(&post, &response); | |
136 } else { | |
137 EXPECT_TRUE(false) << "Unknown/unsupported ClientToServerMessage"; | |
138 return false; | |
139 } | |
140 if (client_command_.get()) { | |
141 response.mutable_client_command()->CopyFrom(*client_command_.get()); | |
142 } | |
143 | |
144 { | |
145 base::AutoLock lock(response_code_override_lock_); | |
146 if (throttling_) { | |
147 response.set_error_code(SyncEnums::THROTTLED); | |
148 throttling_ = false; | |
149 } | |
150 | |
151 if (fail_with_auth_invalid_) | |
152 response.set_error_code(SyncEnums::AUTH_INVALID); | |
153 } | |
154 | |
155 response.SerializeToString(¶ms->buffer_out); | |
156 if (post.message_contents() == ClientToServerMessage::COMMIT && | |
157 !mid_commit_callback_.is_null()) { | |
158 mid_commit_callback_.Run(); | |
159 } | |
160 if (mid_commit_observer_) { | |
161 mid_commit_observer_->Observe(); | |
162 } | |
163 | |
164 return result; | |
165 } | |
166 | |
167 bool MockConnectionManager::IsServerReachable() { | |
168 return true; | |
169 } | |
170 | |
171 bool MockConnectionManager::IsUserAuthenticated() { | |
172 return true; | |
173 } | |
174 | |
175 sync_pb::GetUpdatesResponse* MockConnectionManager::GetUpdateResponse() { | |
176 if (update_queue_.empty()) { | |
177 NextUpdateBatch(); | |
178 } | |
179 return &update_queue_.back(); | |
180 } | |
181 | |
182 void MockConnectionManager::AddDefaultBookmarkData(sync_pb::SyncEntity* entity, | |
183 bool is_folder) { | |
184 if (use_legacy_bookmarks_protocol_) { | |
185 sync_pb::SyncEntity_BookmarkData* data = entity->mutable_bookmarkdata(); | |
186 data->set_bookmark_folder(is_folder); | |
187 | |
188 if (!is_folder) { | |
189 data->set_bookmark_url("http://google.com"); | |
190 } | |
191 } else { | |
192 entity->set_folder(is_folder); | |
193 entity->mutable_specifics()->mutable_bookmark(); | |
194 if (!is_folder) { | |
195 entity->mutable_specifics()->mutable_bookmark()-> | |
196 set_url("http://google.com"); | |
197 } | |
198 } | |
199 } | |
200 | |
201 SyncEntity* MockConnectionManager::AddUpdateDirectory(int id, | |
202 int parent_id, | |
203 string name, | |
204 int64 version, | |
205 int64 sync_ts) { | |
206 return AddUpdateDirectory(TestIdFactory::FromNumber(id), | |
207 TestIdFactory::FromNumber(parent_id), | |
208 name, | |
209 version, | |
210 sync_ts); | |
211 } | |
212 | |
213 sync_pb::ClientCommand* MockConnectionManager::GetNextClientCommand() { | |
214 if (!client_command_.get()) | |
215 client_command_.reset(new sync_pb::ClientCommand()); | |
216 return client_command_.get(); | |
217 } | |
218 | |
219 SyncEntity* MockConnectionManager::AddUpdateBookmark(int id, int parent_id, | |
220 string name, int64 version, | |
221 int64 sync_ts) { | |
222 return AddUpdateBookmark(TestIdFactory::FromNumber(id), | |
223 TestIdFactory::FromNumber(parent_id), | |
224 name, | |
225 version, | |
226 sync_ts); | |
227 } | |
228 | |
229 SyncEntity* MockConnectionManager::AddUpdateSpecifics( | |
230 int id, int parent_id, string name, int64 version, int64 sync_ts, | |
231 bool is_dir, int64 position, const sync_pb::EntitySpecifics& specifics) { | |
232 SyncEntity* ent = AddUpdateMeta( | |
233 TestIdFactory::FromNumber(id).GetServerId(), | |
234 TestIdFactory::FromNumber(parent_id).GetServerId(), | |
235 name, version, sync_ts); | |
236 ent->set_position_in_parent(position); | |
237 ent->mutable_specifics()->CopyFrom(specifics); | |
238 ent->set_folder(is_dir); | |
239 return ent; | |
240 } | |
241 | |
242 sync_pb::SyncEntity* MockConnectionManager::SetNigori( | |
243 int id, int64 version,int64 sync_ts, | |
244 const sync_pb::EntitySpecifics& specifics) { | |
245 SyncEntity* ent = GetUpdateResponse()->add_entries(); | |
246 ent->set_id_string(TestIdFactory::FromNumber(id).GetServerId()); | |
247 ent->set_parent_id_string(TestIdFactory::FromNumber(0).GetServerId()); | |
248 ent->set_server_defined_unique_tag(syncable::ModelTypeToRootTag( | |
249 syncable::NIGORI)); | |
250 ent->set_name("Nigori"); | |
251 ent->set_non_unique_name("Nigori"); | |
252 ent->set_version(version); | |
253 ent->set_sync_timestamp(sync_ts); | |
254 ent->set_mtime(sync_ts); | |
255 ent->set_ctime(1); | |
256 ent->set_position_in_parent(0); | |
257 ent->set_folder(false); | |
258 ent->mutable_specifics()->CopyFrom(specifics); | |
259 return ent; | |
260 } | |
261 | |
262 SyncEntity* MockConnectionManager::AddUpdateFull(string id, string parent_id, | |
263 string name, int64 version, | |
264 int64 sync_ts, bool is_dir) { | |
265 SyncEntity* ent = AddUpdateMeta(id, parent_id, name, version, sync_ts); | |
266 AddDefaultBookmarkData(ent, is_dir); | |
267 return ent; | |
268 } | |
269 | |
270 SyncEntity* MockConnectionManager::AddUpdateMeta(string id, string parent_id, | |
271 string name, int64 version, | |
272 int64 sync_ts) { | |
273 SyncEntity* ent = GetUpdateResponse()->add_entries(); | |
274 ent->set_id_string(id); | |
275 ent->set_parent_id_string(parent_id); | |
276 ent->set_non_unique_name(name); | |
277 ent->set_name(name); | |
278 ent->set_version(version); | |
279 ent->set_sync_timestamp(sync_ts); | |
280 ent->set_mtime(sync_ts); | |
281 ent->set_ctime(1); | |
282 ent->set_position_in_parent(GeneratePositionInParent()); | |
283 return ent; | |
284 } | |
285 | |
286 SyncEntity* MockConnectionManager::AddUpdateDirectory(string id, | |
287 string parent_id, | |
288 string name, | |
289 int64 version, | |
290 int64 sync_ts) { | |
291 return AddUpdateFull(id, parent_id, name, version, sync_ts, true); | |
292 } | |
293 | |
294 SyncEntity* MockConnectionManager::AddUpdateBookmark(string id, | |
295 string parent_id, | |
296 string name, int64 version, | |
297 int64 sync_ts) { | |
298 return AddUpdateFull(id, parent_id, name, version, sync_ts, false); | |
299 } | |
300 | |
301 SyncEntity* MockConnectionManager::AddUpdateFromLastCommit() { | |
302 EXPECT_EQ(1, last_sent_commit().entries_size()); | |
303 EXPECT_EQ(1, last_commit_response().entryresponse_size()); | |
304 EXPECT_EQ(CommitResponse::SUCCESS, | |
305 last_commit_response().entryresponse(0).response_type()); | |
306 | |
307 if (last_sent_commit().entries(0).deleted()) { | |
308 AddUpdateTombstone(syncable::Id::CreateFromServerId( | |
309 last_sent_commit().entries(0).id_string())); | |
310 } else { | |
311 SyncEntity* ent = GetUpdateResponse()->add_entries(); | |
312 ent->CopyFrom(last_sent_commit().entries(0)); | |
313 ent->clear_insert_after_item_id(); | |
314 ent->clear_old_parent_id(); | |
315 ent->set_position_in_parent( | |
316 last_commit_response().entryresponse(0).position_in_parent()); | |
317 ent->set_version( | |
318 last_commit_response().entryresponse(0).version()); | |
319 ent->set_id_string( | |
320 last_commit_response().entryresponse(0).id_string()); | |
321 // Tests don't currently care about the following: | |
322 // originator_cache_guid, originator_client_item_id, parent_id_string, | |
323 // name, non_unique_name. | |
324 } | |
325 return GetMutableLastUpdate(); | |
326 } | |
327 | |
328 void MockConnectionManager::AddUpdateTombstone(const syncable::Id& id) { | |
329 // Tombstones have only the ID set and dummy values for the required fields. | |
330 SyncEntity* ent = GetUpdateResponse()->add_entries(); | |
331 ent->set_id_string(id.GetServerId()); | |
332 ent->set_version(0); | |
333 ent->set_name(""); | |
334 ent->set_deleted(true); | |
335 } | |
336 | |
337 void MockConnectionManager::SetLastUpdateDeleted() { | |
338 // Tombstones have only the ID set. Wipe anything else. | |
339 string id_string = GetMutableLastUpdate()->id_string(); | |
340 GetUpdateResponse()->mutable_entries()->RemoveLast(); | |
341 AddUpdateTombstone(syncable::Id::CreateFromServerId(id_string)); | |
342 } | |
343 | |
344 void MockConnectionManager::SetLastUpdateOriginatorFields( | |
345 const string& client_id, | |
346 const string& entry_id) { | |
347 GetMutableLastUpdate()->set_originator_cache_guid(client_id); | |
348 GetMutableLastUpdate()->set_originator_client_item_id(entry_id); | |
349 } | |
350 | |
351 void MockConnectionManager::SetLastUpdateServerTag(const string& tag) { | |
352 GetMutableLastUpdate()->set_server_defined_unique_tag(tag); | |
353 } | |
354 | |
355 void MockConnectionManager::SetLastUpdateClientTag(const string& tag) { | |
356 GetMutableLastUpdate()->set_client_defined_unique_tag(tag); | |
357 } | |
358 | |
359 void MockConnectionManager::SetLastUpdatePosition(int64 server_position) { | |
360 GetMutableLastUpdate()->set_position_in_parent(server_position); | |
361 } | |
362 | |
363 void MockConnectionManager::SetNewTimestamp(int ts) { | |
364 next_token_ = base::StringPrintf("mock connection ts = %d", ts); | |
365 ApplyToken(); | |
366 } | |
367 | |
368 void MockConnectionManager::ApplyToken() { | |
369 if (!update_queue_.empty()) { | |
370 GetUpdateResponse()->clear_new_progress_marker(); | |
371 sync_pb::DataTypeProgressMarker* new_marker = | |
372 GetUpdateResponse()->add_new_progress_marker(); | |
373 new_marker->set_data_type_id(-1); // Invalid -- clients shouldn't see. | |
374 new_marker->set_token(next_token_); | |
375 } | |
376 } | |
377 | |
378 void MockConnectionManager::SetChangesRemaining(int64 timestamp) { | |
379 GetUpdateResponse()->set_changes_remaining(timestamp); | |
380 } | |
381 | |
382 void MockConnectionManager::ProcessGetUpdates(ClientToServerMessage* csm, | |
383 ClientToServerResponse* response) { | |
384 CHECK(csm->has_get_updates()); | |
385 ASSERT_EQ(csm->message_contents(), ClientToServerMessage::GET_UPDATES); | |
386 const GetUpdatesMessage& gu = csm->get_updates(); | |
387 num_get_updates_requests_++; | |
388 EXPECT_FALSE(gu.has_from_timestamp()); | |
389 EXPECT_FALSE(gu.has_requested_types()); | |
390 | |
391 if (fail_non_periodic_get_updates_) { | |
392 EXPECT_EQ(sync_pb::GetUpdatesCallerInfo::PERIODIC, | |
393 gu.caller_info().source()); | |
394 } | |
395 | |
396 // Verify that the GetUpdates filter sent by the Syncer matches the test | |
397 // expectation. | |
398 for (int i = FIRST_REAL_MODEL_TYPE; i < MODEL_TYPE_COUNT; ++i) { | |
399 ModelType model_type = syncable::ModelTypeFromInt(i); | |
400 sync_pb::DataTypeProgressMarker const* progress_marker = | |
401 GetProgressMarkerForType(gu.from_progress_marker(), model_type); | |
402 EXPECT_EQ(expected_filter_.Has(model_type), (progress_marker != NULL)) | |
403 << "Syncer requested_types differs from test expectation."; | |
404 if (progress_marker) { | |
405 EXPECT_EQ((expected_payloads_.count(model_type) > 0 ? | |
406 expected_payloads_[model_type] : | |
407 std::string()), | |
408 progress_marker->notification_hint()); | |
409 } | |
410 } | |
411 | |
412 // Verify that the items we're about to send back to the client are of | |
413 // the types requested by the client. If this fails, it probably indicates | |
414 // a test bug. | |
415 EXPECT_TRUE(gu.fetch_folders()); | |
416 EXPECT_FALSE(gu.has_requested_types()); | |
417 if (update_queue_.empty()) { | |
418 GetUpdateResponse(); | |
419 } | |
420 sync_pb::GetUpdatesResponse* updates = &update_queue_.front(); | |
421 for (int i = 0; i < updates->entries_size(); ++i) { | |
422 if (!updates->entries(i).deleted()) { | |
423 ModelType entry_type = syncable::GetModelType(updates->entries(i)); | |
424 EXPECT_TRUE( | |
425 IsModelTypePresentInSpecifics(gu.from_progress_marker(), entry_type)) | |
426 << "Syncer did not request updates being provided by the test."; | |
427 } | |
428 } | |
429 | |
430 response->mutable_get_updates()->CopyFrom(*updates); | |
431 | |
432 // Set appropriate progress markers, overriding the value squirreled | |
433 // away by ApplyToken(). | |
434 std::string token = response->get_updates().new_progress_marker(0).token(); | |
435 response->mutable_get_updates()->clear_new_progress_marker(); | |
436 for (int i = 0; i < gu.from_progress_marker_size(); ++i) { | |
437 if (gu.from_progress_marker(i).token() != token) { | |
438 sync_pb::DataTypeProgressMarker* new_marker = | |
439 response->mutable_get_updates()->add_new_progress_marker(); | |
440 new_marker->set_data_type_id(gu.from_progress_marker(i).data_type_id()); | |
441 new_marker->set_token(token); | |
442 } | |
443 } | |
444 | |
445 update_queue_.pop_front(); | |
446 } | |
447 | |
448 void MockConnectionManager::SetClearUserDataResponseStatus( | |
449 sync_pb::SyncEnums::ErrorType errortype ) { | |
450 // Note: this is not a thread-safe set, ok for now. NOT ok if tests | |
451 // run the syncer on the background thread while this method is called. | |
452 clear_user_data_response_errortype_ = errortype; | |
453 } | |
454 | |
455 void MockConnectionManager::ProcessClearData(ClientToServerMessage* csm, | |
456 ClientToServerResponse* response) { | |
457 CHECK(csm->has_clear_user_data()); | |
458 ASSERT_EQ(csm->message_contents(), ClientToServerMessage::CLEAR_DATA); | |
459 response->clear_user_data(); | |
460 response->set_error_code(clear_user_data_response_errortype_); | |
461 } | |
462 | |
463 void MockConnectionManager::ProcessAuthenticate( | |
464 ClientToServerMessage* csm, | |
465 ClientToServerResponse* response, | |
466 const std::string& auth_token) { | |
467 ASSERT_EQ(csm->message_contents(), ClientToServerMessage::AUTHENTICATE); | |
468 EXPECT_FALSE(auth_token.empty()); | |
469 | |
470 if (auth_token != valid_auth_token_) { | |
471 response->set_error_code(SyncEnums::AUTH_INVALID); | |
472 return; | |
473 } | |
474 | |
475 response->set_error_code(SyncEnums::SUCCESS); | |
476 response->mutable_authenticate()->CopyFrom(auth_response_); | |
477 auth_response_.Clear(); | |
478 } | |
479 | |
480 void MockConnectionManager::SetAuthenticationResponseInfo( | |
481 const std::string& valid_auth_token, | |
482 const std::string& user_display_name, | |
483 const std::string& user_display_email, | |
484 const std::string& user_obfuscated_id) { | |
485 valid_auth_token_ = valid_auth_token; | |
486 sync_pb::UserIdentification* user = auth_response_.mutable_user(); | |
487 user->set_display_name(user_display_name); | |
488 user->set_email(user_display_email); | |
489 user->set_obfuscated_id(user_obfuscated_id); | |
490 } | |
491 | |
492 bool MockConnectionManager::ShouldConflictThisCommit() { | |
493 bool conflict = false; | |
494 if (conflict_all_commits_) { | |
495 conflict = true; | |
496 } else if (conflict_n_commits_ > 0) { | |
497 conflict = true; | |
498 --conflict_n_commits_; | |
499 } | |
500 return conflict; | |
501 } | |
502 | |
503 void MockConnectionManager::ProcessCommit(ClientToServerMessage* csm, | |
504 ClientToServerResponse* response_buffer) { | |
505 CHECK(csm->has_commit()); | |
506 ASSERT_EQ(csm->message_contents(), ClientToServerMessage::COMMIT); | |
507 map <string, string> changed_ids; | |
508 const CommitMessage& commit_message = csm->commit(); | |
509 CommitResponse* commit_response = response_buffer->mutable_commit(); | |
510 commit_messages_->push_back(new CommitMessage); | |
511 commit_messages_->back()->CopyFrom(commit_message); | |
512 map<string, CommitResponse_EntryResponse*> response_map; | |
513 for (int i = 0; i < commit_message.entries_size() ; i++) { | |
514 const sync_pb::SyncEntity& entry = commit_message.entries(i); | |
515 CHECK(entry.has_id_string()); | |
516 string id = entry.id_string(); | |
517 ASSERT_LT(entry.name().length(), 256ul) << " name probably too long. True " | |
518 "server name checking not implemented"; | |
519 if (entry.version() == 0) { | |
520 // Relies on our new item string id format. (string representation of a | |
521 // negative number). | |
522 committed_ids_.push_back(syncable::Id::CreateFromClientString(id)); | |
523 } else { | |
524 committed_ids_.push_back(syncable::Id::CreateFromServerId(id)); | |
525 } | |
526 if (response_map.end() == response_map.find(id)) | |
527 response_map[id] = commit_response->add_entryresponse(); | |
528 CommitResponse_EntryResponse* er = response_map[id]; | |
529 if (ShouldConflictThisCommit()) { | |
530 er->set_response_type(CommitResponse::CONFLICT); | |
531 continue; | |
532 } | |
533 er->set_response_type(CommitResponse::SUCCESS); | |
534 er->set_version(entry.version() + 1); | |
535 if (!commit_time_rename_prepended_string_.empty()) { | |
536 // Commit time rename sent down from the server. | |
537 er->set_name(commit_time_rename_prepended_string_ + entry.name()); | |
538 } | |
539 string parent_id = entry.parent_id_string(); | |
540 // Remap id's we've already assigned. | |
541 if (changed_ids.end() != changed_ids.find(parent_id)) { | |
542 parent_id = changed_ids[parent_id]; | |
543 er->set_parent_id_string(parent_id); | |
544 } | |
545 if (entry.has_version() && 0 != entry.version()) { | |
546 er->set_id_string(id); // Allows verification. | |
547 } else { | |
548 string new_id = base::StringPrintf("mock_server:%d", next_new_id_++); | |
549 changed_ids[id] = new_id; | |
550 er->set_id_string(new_id); | |
551 } | |
552 } | |
553 commit_responses_->push_back(new CommitResponse(*commit_response)); | |
554 } | |
555 | |
556 SyncEntity* MockConnectionManager::AddUpdateDirectory( | |
557 syncable::Id id, syncable::Id parent_id, string name, int64 version, | |
558 int64 sync_ts) { | |
559 return AddUpdateDirectory(id.GetServerId(), parent_id.GetServerId(), | |
560 name, version, sync_ts); | |
561 } | |
562 | |
563 SyncEntity* MockConnectionManager::AddUpdateBookmark( | |
564 syncable::Id id, syncable::Id parent_id, string name, int64 version, | |
565 int64 sync_ts) { | |
566 return AddUpdateBookmark(id.GetServerId(), parent_id.GetServerId(), | |
567 name, version, sync_ts); | |
568 } | |
569 | |
570 SyncEntity* MockConnectionManager::GetMutableLastUpdate() { | |
571 sync_pb::GetUpdatesResponse* updates = GetUpdateResponse(); | |
572 EXPECT_GT(updates->entries_size(), 0); | |
573 return updates->mutable_entries()->Mutable(updates->entries_size() - 1); | |
574 } | |
575 | |
576 void MockConnectionManager::NextUpdateBatch() { | |
577 update_queue_.push_back(sync_pb::GetUpdatesResponse::default_instance()); | |
578 SetChangesRemaining(0); | |
579 ApplyToken(); | |
580 } | |
581 | |
582 const CommitMessage& MockConnectionManager::last_sent_commit() const { | |
583 EXPECT_TRUE(!commit_messages_.empty()); | |
584 return *commit_messages_->back(); | |
585 } | |
586 | |
587 const CommitResponse& MockConnectionManager::last_commit_response() const { | |
588 EXPECT_TRUE(!commit_responses_.empty()); | |
589 return *commit_responses_->back(); | |
590 } | |
591 | |
592 void MockConnectionManager::ThrottleNextRequest( | |
593 ResponseCodeOverrideRequestor* visitor) { | |
594 base::AutoLock lock(response_code_override_lock_); | |
595 throttling_ = true; | |
596 if (visitor) | |
597 visitor->OnOverrideComplete(); | |
598 } | |
599 | |
600 void MockConnectionManager::FailWithAuthInvalid( | |
601 ResponseCodeOverrideRequestor* visitor) { | |
602 base::AutoLock lock(response_code_override_lock_); | |
603 fail_with_auth_invalid_ = true; | |
604 if (visitor) | |
605 visitor->OnOverrideComplete(); | |
606 } | |
607 | |
608 void MockConnectionManager::StopFailingWithAuthInvalid( | |
609 ResponseCodeOverrideRequestor* visitor) { | |
610 base::AutoLock lock(response_code_override_lock_); | |
611 fail_with_auth_invalid_ = false; | |
612 if (visitor) | |
613 visitor->OnOverrideComplete(); | |
614 } | |
615 | |
616 bool MockConnectionManager::IsModelTypePresentInSpecifics( | |
617 const google::protobuf::RepeatedPtrField< | |
618 sync_pb::DataTypeProgressMarker>& filter, | |
619 syncable::ModelType value) { | |
620 int data_type_id = syncable::GetSpecificsFieldNumberFromModelType(value); | |
621 for (int i = 0; i < filter.size(); ++i) { | |
622 if (filter.Get(i).data_type_id() == data_type_id) { | |
623 return true; | |
624 } | |
625 } | |
626 return false; | |
627 } | |
628 | |
629 sync_pb::DataTypeProgressMarker const* | |
630 MockConnectionManager::GetProgressMarkerForType( | |
631 const google::protobuf::RepeatedPtrField< | |
632 sync_pb::DataTypeProgressMarker>& filter, | |
633 syncable::ModelType value) { | |
634 int data_type_id = syncable::GetSpecificsFieldNumberFromModelType(value); | |
635 for (int i = 0; i < filter.size(); ++i) { | |
636 if (filter.Get(i).data_type_id() == data_type_id) { | |
637 return &(filter.Get(i)); | |
638 } | |
639 } | |
640 return NULL; | |
641 } | |
642 | |
643 void MockConnectionManager::SetServerReachable() { | |
644 server_status_ = HttpResponse::SERVER_CONNECTION_OK; | |
645 server_reachable_ = true; | |
646 | |
647 FOR_EACH_OBSERVER(ServerConnectionEventListener, listeners_, | |
648 OnServerConnectionEvent( | |
649 ServerConnectionEvent(server_status_, server_reachable_))); | |
650 } | |
651 | |
652 void MockConnectionManager::SetServerNotReachable() { | |
653 server_status_ = HttpResponse::CONNECTION_UNAVAILABLE; | |
654 server_reachable_ = false; | |
655 | |
656 FOR_EACH_OBSERVER(ServerConnectionEventListener, listeners_, | |
657 OnServerConnectionEvent( | |
658 ServerConnectionEvent(server_status_, server_reachable_))); | |
659 } | |
OLD | NEW |