Index: chrome/test/sync/engine/mock_server_connection.cc |
=================================================================== |
--- chrome/test/sync/engine/mock_server_connection.cc (revision 0) |
+++ chrome/test/sync/engine/mock_server_connection.cc (revision 0) |
@@ -0,0 +1,338 @@ |
+// Copyright (c) 2009 The Chromium Authors. All rights reserved. |
+// Use of this source code is governed by a BSD-style license that can be |
+// found in the LICENSE file. |
+// |
+// Mock ServerConnectionManager class for use in client regression tests. |
+// |
+ |
+#include "chrome/test/sync/engine/mock_server_connection.h" |
+ |
+#include "chrome/browser/sync/engine/syncer_proto_util.h" |
+#include "chrome/browser/sync/util/character_set_converters.h" |
+#include "chrome/test/sync/engine/test_id_factory.h" |
+#include "testing/gtest/include/gtest/gtest.h" |
+ |
+using browser_sync::HttpResponse; |
+using browser_sync::ServerConnectionManager; |
+using browser_sync::SyncerProtoUtil; |
+using browser_sync::TestIdFactory; |
+using std::map; |
+using std::string; |
+using sync_pb::ClientToServerMessage; |
+using sync_pb::ClientToServerResponse; |
+using sync_pb::CommitMessage; |
+using sync_pb::CommitResponse; |
+using sync_pb::CommitResponse_EntryResponse; |
+using sync_pb::GetUpdatesMessage; |
+using sync_pb::SyncEntity; |
+using syncable::DirectoryManager; |
+using syncable::WriteTransaction; |
+ |
+MockConnectionManager::MockConnectionManager(DirectoryManager* dirmgr, |
+ PathString name) |
+ : ServerConnectionManager("unused", 0, false, "version", "id"), |
+ conflict_all_commits_(false), |
+ conflict_n_commits_(0), |
+ next_new_id_(10000), |
+ store_birthday_("Store BDay!"), |
+ store_birthday_sent_(false), |
+ client_stuck_(false), |
+ commit_time_rename_prepended_string_(""), |
+ fail_next_postbuffer_(false), |
+ directory_(dirmgr, name), |
+ mid_commit_callback_function_(NULL), |
+ client_command_(NULL), |
+ next_position_in_parent_(2) { |
+ server_reachable_ = true; |
+ CHECK(directory_.good()); |
+}; |
+ |
+MockConnectionManager::~MockConnectionManager() { |
+ for (size_t i = 0; i < commit_messages_.size(); i++) |
+ delete commit_messages_[i]; |
+} |
+ |
+void MockConnectionManager::SetCommitTimeRename(string prepend) { |
+ commit_time_rename_prepended_string_ = prepend; |
+} |
+ |
+void MockConnectionManager::SetMidCommitCallbackFunction( |
+ MockConnectionManager::TestCallbackFunction callback) { |
+ mid_commit_callback_function_ = callback; |
+} |
+ |
+bool MockConnectionManager::PostBufferToPath(const PostBufferParams* params, |
+ const string& path, |
+ const string& auth_token) { |
+ ClientToServerMessage post; |
+ CHECK(post.ParseFromString(params->buffer_in)); |
+ client_stuck_ = post.sync_problem_detected(); |
+ ClientToServerResponse response; |
+ response.Clear(); |
+ // If the Directory's locked when we do this, it's a problem as in normal |
+ // use this function could take a while to return because it accesses the |
+ // network. As we can't test this we do the next best thing and hang here |
+ // when there's an issue. |
+ { |
+ WriteTransaction wt(directory_, syncable::UNITTEST, __FILE__, __LINE__); |
+ } |
+ if (fail_next_postbuffer_) { |
+ fail_next_postbuffer_ = false; |
+ return false; |
+ } |
+ // Default to an ok connection. |
+ params->response->server_status = HttpResponse::SERVER_CONNECTION_OK; |
+ response.set_store_birthday(store_birthday_); |
+ if (post.has_store_birthday() && post.store_birthday() != store_birthday_) { |
+ response.set_error_code(ClientToServerResponse::NOT_MY_BIRTHDAY); |
+ response.set_error_message("Merry Unbirthday!"); |
+ response.SerializeToString(params->buffer_out); |
+ store_birthday_sent_ = true; |
+ return true; |
+ } |
+ bool result = true; |
+ EXPECT_TRUE(!store_birthday_sent_ || post.has_store_birthday()); |
+ store_birthday_sent_ = true; |
+ if (post.message_contents() == ClientToServerMessage::COMMIT) { |
+ ProcessCommit(&post, &response); |
+ } else if (post.message_contents() == ClientToServerMessage::GET_UPDATES) { |
+ ProcessGetUpdates(&post, &response); |
+ } else { |
+ EXPECT_TRUE(false) << "Unknown/unsupported ClientToServerMessage"; |
+ return false; |
+ } |
+ if (client_command_.get()) { |
+ response.mutable_client_command()->CopyFrom(*client_command_.get()); |
+ } |
+ response.SerializeToString(params->buffer_out); |
+ if (mid_commit_callback_function_) { |
+ if (mid_commit_callback_function_(directory_)) |
+ mid_commit_callback_function_ = 0; |
+ } |
+ return result; |
+} |
+ |
+bool MockConnectionManager::IsServerReachable() { |
+ return true; |
+} |
+ |
+bool MockConnectionManager::IsUserAuthenticated() { |
+ return true; |
+} |
+ |
+void MockConnectionManager::ResetUpdates() { |
+ updates_.Clear(); |
+} |
+ |
+namespace { |
+ |
+void AddDefaultBookmarkData(SyncEntity* entity, bool is_folder) { |
+ sync_pb::SyncEntity_BookmarkData* data = entity->mutable_bookmarkdata(); |
+ data->set_bookmark_folder(is_folder); |
+ |
+ if (!is_folder) { |
+ data->set_bookmark_url("http://google.com"); |
+ } |
+} |
+ |
+} // namespace |
+ |
+SyncEntity* MockConnectionManager::AddUpdateDirectory(int id, |
+ int parent_id, |
+ string name, |
+ int64 version, |
+ int64 sync_ts) { |
+ return AddUpdateDirectory(TestIdFactory::FromNumber(id), |
+ TestIdFactory::FromNumber(parent_id), |
+ name, |
+ version, |
+ sync_ts); |
+} |
+ |
+sync_pb::ClientCommand* MockConnectionManager::GetNextClientCommand() { |
+ if (!client_command_.get()) |
+ client_command_.reset(new sync_pb::ClientCommand()); |
+ return client_command_.get(); |
+} |
+ |
+SyncEntity* MockConnectionManager::AddUpdateBookmark(int id, int parent_id, |
+ string name, int64 version, |
+ int64 sync_ts) { |
+ return AddUpdateBookmark(TestIdFactory::FromNumber(id), |
+ TestIdFactory::FromNumber(parent_id), |
+ name, |
+ version, |
+ sync_ts); |
+} |
+ |
+SyncEntity* MockConnectionManager::AddUpdateFull(string id, string parent_id, |
+ string name, int64 version, |
+ int64 sync_ts, bool is_dir) { |
+ SyncEntity* ent = updates_.add_entries(); |
+ ent->set_id_string(id); |
+ ent->set_parent_id_string(parent_id); |
+ ent->set_name(name); |
+ ent->set_version(version); |
+ ent->set_sync_timestamp(sync_ts); |
+ ent->set_mtime(sync_ts); |
+ ent->set_ctime(1); |
+ ent->set_position_in_parent(GeneratePositionInParent()); |
+ AddDefaultBookmarkData(ent, is_dir); |
+ if (sync_ts > updates_.newest_timestamp()) |
+ updates_.set_newest_timestamp(sync_ts); |
+ return ent; |
+} |
+ |
+SyncEntity* MockConnectionManager::AddUpdateDirectory(string id, |
+ string parent_id, |
+ string name, |
+ int64 version, |
+ int64 sync_ts) { |
+ return AddUpdateFull(id, parent_id, name, version, sync_ts, true); |
+} |
+ |
+SyncEntity* MockConnectionManager::AddUpdateBookmark(string id, |
+ string parent_id, |
+ string name, int64 version, |
+ int64 sync_ts) { |
+ return AddUpdateFull(id, parent_id, name, version, sync_ts, false); |
+} |
+ |
+void MockConnectionManager::SetLastUpdateDeleted() { |
+ GetMutableLastUpdate()->set_deleted(true); |
+} |
+ |
+void MockConnectionManager::SetLastUpdateOriginatorFields( |
+ const string& client_id, |
+ const string& entry_id) { |
+ GetMutableLastUpdate()->set_originator_cache_guid(client_id); |
+ GetMutableLastUpdate()->set_originator_client_item_id(entry_id); |
+} |
+ |
+void MockConnectionManager::SetLastUpdateSingletonTag(const string& tag) { |
+ GetMutableLastUpdate()->set_singleton_tag(tag); |
+} |
+ |
+void MockConnectionManager::SetLastUpdatePosition(int64 server_position) { |
+ GetMutableLastUpdate()->set_position_in_parent(server_position); |
+} |
+ |
+void MockConnectionManager::SetNewTimestamp(int64 ts) { |
+ updates_.set_new_timestamp(ts); |
+} |
+ |
+void MockConnectionManager::SetNewestTimestamp(int64 ts) { |
+ updates_.set_newest_timestamp(ts); |
+} |
+ |
+void MockConnectionManager::ProcessGetUpdates(ClientToServerMessage* csm, |
+ ClientToServerResponse* response) { |
+ CHECK(csm->has_get_updates()); |
+ ASSERT_EQ(csm->message_contents(), ClientToServerMessage::GET_UPDATES); |
+ const GetUpdatesMessage& gu = csm->get_updates(); |
+ EXPECT_TRUE(gu.has_from_timestamp()); |
+ // TODO(sync): filter results dependant on timestamp? or check limits? |
+ response->mutable_get_updates()->CopyFrom(updates_); |
+ ResetUpdates(); |
+} |
+ |
+bool MockConnectionManager::ShouldConflictThisCommit() { |
+ bool conflict = false; |
+ if (conflict_all_commits_) { |
+ conflict = true; |
+ } else if (conflict_n_commits_ > 0) { |
+ conflict = true; |
+ --conflict_n_commits_; |
+ } |
+ return conflict; |
+} |
+ |
+void MockConnectionManager::ProcessCommit(ClientToServerMessage* csm, |
+ ClientToServerResponse* response_buffer) { |
+ CHECK(csm->has_commit()); |
+ ASSERT_EQ(csm->message_contents(), ClientToServerMessage::COMMIT); |
+ map <string, string> changed_ids; |
+ const CommitMessage& commit_message = csm->commit(); |
+ CommitResponse* commit_response = response_buffer->mutable_commit(); |
+ commit_messages_.push_back(new CommitMessage); |
+ commit_messages_.back()->CopyFrom(commit_message); |
+ map<string, CommitResponse_EntryResponse*> response_map; |
+ for (int i = 0; i < commit_message.entries_size() ; i++) { |
+ const sync_pb::SyncEntity& entry = commit_message.entries(i); |
+ CHECK(entry.has_id_string()); |
+ string id = entry.id_string(); |
+ ASSERT_LT(entry.name().length(), 256ul) << " name probably too long. True " |
+ "server name checking not implemented"; |
+ if (entry.version() == 0) { |
+ // relys on our new item string id format. (string representation of a |
+ // negative number) |
+ committed_ids_.push_back(syncable::Id::CreateFromClientString(id)); |
+ } else { |
+ committed_ids_.push_back(syncable::Id::CreateFromServerId(id)); |
+ } |
+ if (response_map.end() == response_map.find(id)) |
+ response_map[id] = commit_response->add_entryresponse(); |
+ CommitResponse_EntryResponse* er = response_map[id]; |
+ if (ShouldConflictThisCommit()) { |
+ er->set_response_type(CommitResponse::CONFLICT); |
+ continue; |
+ } |
+ er->set_response_type(CommitResponse::SUCCESS); |
+ er->set_version(entry.version() + 1); |
+ if (!commit_time_rename_prepended_string_.empty()) { |
+ // Commit time rename sent down from the server |
+ er->set_name(commit_time_rename_prepended_string_ + entry.name()); |
+ } |
+ string parent_id = entry.parent_id_string(); |
+ // Remap id's we've already assigned |
+ if (changed_ids.end() != changed_ids.find(parent_id)) { |
+ parent_id = changed_ids[parent_id]; |
+ er->set_parent_id_string(parent_id); |
+ } |
+ if (entry.has_version() && 0 != entry.version()) { |
+ er->set_id_string(id); // allows verification |
+ } else { |
+ string new_id = StringPrintf("mock_server:%d", next_new_id_++); |
+ changed_ids[id] = new_id; |
+ er->set_id_string(new_id); |
+ } |
+ } |
+} |
+ |
+SyncEntity* MockConnectionManager::AddUpdateDirectory( |
+ syncable::Id id, syncable::Id parent_id, string name, int64 version, |
+ int64 sync_ts) { |
+ return AddUpdateDirectory(id.GetServerId(), parent_id.GetServerId(), |
+ name, version, sync_ts); |
+} |
+ |
+SyncEntity* MockConnectionManager::AddUpdateBookmark( |
+ syncable::Id id, syncable::Id parent_id, string name, int64 version, |
+ int64 sync_ts) { |
+ return AddUpdateBookmark(id.GetServerId(), parent_id.GetServerId(), |
+ name, version, sync_ts); |
+} |
+ |
+void MockConnectionManager::AddUpdateExtendedAttributes(SyncEntity* ent, |
+ PathString* xattr_key, syncable::Blob* xattr_value, int xattr_count) { |
+ sync_pb::ExtendedAttributes* mutable_extended_attributes = |
+ ent->mutable_extended_attributes(); |
+ for (int i = 0; i < xattr_count; i++) { |
+ sync_pb::ExtendedAttributes_ExtendedAttribute* extended_attribute = |
+ mutable_extended_attributes->add_extendedattribute(); |
+ extended_attribute->set_key(static_cast<const string&> |
+ (browser_sync::ToUTF8(xattr_key[i]))); |
+ SyncerProtoUtil::CopyBlobIntoProtoBytes(xattr_value[i], |
+ extended_attribute->mutable_value()); |
+ } |
+} |
+ |
+SyncEntity* MockConnectionManager::GetMutableLastUpdate() { |
+ DCHECK(updates_.entries_size() > 0); |
+ return updates_.mutable_entries()->Mutable(updates_.entries_size() - 1); |
+} |
+ |
+const CommitMessage& MockConnectionManager::last_sent_commit() const { |
+ DCHECK(!commit_messages_.empty()); |
+ return *commit_messages_.back(); |
+} |
Property changes on: chrome\test\sync\engine\mock_server_connection.cc |
___________________________________________________________________ |
Added: svn:eol-style |
+ LF |