diff options
author | nick@chromium.org <nick@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-02-11 01:05:38 +0000 |
---|---|---|
committer | nick@chromium.org <nick@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-02-11 01:05:38 +0000 |
commit | f753af6865f1724c3e5adde6917bb2b1f24713ce (patch) | |
tree | 35a5185cbadcbf66625fb438f893bba4e806ef68 /chrome/test/sync | |
parent | 3d8a66ab748a0bcb5126b1466d311ad62db4d94d (diff) | |
download | chromium_src-f753af6865f1724c3e5adde6917bb2b1f24713ce.zip chromium_src-f753af6865f1724c3e5adde6917bb2b1f24713ce.tar.gz chromium_src-f753af6865f1724c3e5adde6917bb2b1f24713ce.tar.bz2 |
Hook up client side of per-datatype GetUpdates.
Which datatypes are fetched is dictated by the ModelSafeRoutingInfo. We change the semantic of the ModelSafeRoutingInfo so that datatypes which should not be synced are not in the map. We will do GetUpdates for GROUP_PASSIVE datatypes.
BUG=29905
TEST=included unit tests
Review URL: http://codereview.chromium.org/594024
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@38726 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/test/sync')
-rwxr-xr-x | chrome/test/sync/engine/mock_server_connection.cc | 43 | ||||
-rwxr-xr-x | chrome/test/sync/engine/mock_server_connection.h | 42 | ||||
-rwxr-xr-x | chrome/test/sync/engine/proto_extension_validator.h | 56 |
3 files changed, 133 insertions, 8 deletions
diff --git a/chrome/test/sync/engine/mock_server_connection.cc b/chrome/test/sync/engine/mock_server_connection.cc index 9eb751b..cbea2d9 100755 --- a/chrome/test/sync/engine/mock_server_connection.cc +++ b/chrome/test/sync/engine/mock_server_connection.cc @@ -26,6 +26,7 @@ using sync_pb::CommitResponse_EntryResponse; using sync_pb::GetUpdatesMessage; using sync_pb::SyncEntity; using syncable::DirectoryManager; +using syncable::ModelType; using syncable::ScopedDirLookup; using syncable::WriteTransaction; @@ -48,7 +49,8 @@ MockConnectionManager::MockConnectionManager(DirectoryManager* dirmgr, fail_non_periodic_get_updates_(false), client_command_(NULL), next_position_in_parent_(2), - use_legacy_bookmarks_protocol_(false) { + use_legacy_bookmarks_protocol_(false), + num_get_updates_requests_(0) { server_reachable_ = true; }; @@ -275,12 +277,40 @@ void MockConnectionManager::ProcessGetUpdates(ClientToServerMessage* csm, CHECK(csm->has_get_updates()); ASSERT_EQ(csm->message_contents(), ClientToServerMessage::GET_UPDATES); const GetUpdatesMessage& gu = csm->get_updates(); + num_get_updates_requests_++; EXPECT_TRUE(gu.has_from_timestamp()); if (fail_non_periodic_get_updates_) { EXPECT_EQ(sync_pb::GetUpdatesCallerInfo::PERIODIC, gu.caller_info().source()); } + // Verify that the GetUpdates filter sent by the Syncer matches the test + // expectation. + for (int i = 0; i < syncable::MODEL_TYPE_COUNT; ++i) { + if (i == syncable::UNSPECIFIED || i == syncable::TOP_LEVEL_FOLDER) { + DCHECK(!expected_filter_[i]) << "Protocol doesn't support this type."; + continue; + } + ModelType model_type = syncable::ModelTypeFromInt(i); + EXPECT_EQ(expected_filter_[i], + IsModelTypePresentInSpecifics(gu.requested_types(), model_type)) + << "Syncer requested_types differs from test expectation."; + } + + // Verify that the items we're about to send back to the client are of + // the types requested by the client. If this fails, it probably indicates + // a test bug. + EXPECT_TRUE(gu.fetch_folders()); + EXPECT_TRUE(gu.has_requested_types()); + for (int i = 0; i < updates_.entries_size(); ++i) { + if (!updates_.entries(i).deleted()) { + ModelType entry_type = syncable::GetModelType(updates_.entries(i)); + EXPECT_TRUE( + IsModelTypePresentInSpecifics(gu.requested_types(), entry_type)) + << "Syncer did not request updates being provided by the test."; + } + } + // TODO(sync): filter results dependant on timestamp? or check limits? response->mutable_get_updates()->CopyFrom(updates_); ResetUpdates(); @@ -438,3 +468,14 @@ void MockConnectionManager::StopFailingWithAuthInvalid( if (visitor) visitor->OnOverrideComplete(); } + +bool MockConnectionManager::IsModelTypePresentInSpecifics( + const sync_pb::EntitySpecifics& filter, syncable::ModelType value) { + // This implementation is a little contorted; it's done this way + // to avoid having to switch on the ModelType. We're basically doing + // the protobuf equivalent of ((value & filter) == filter). + sync_pb::EntitySpecifics value_filter; + syncable::AddDefaultExtensionValue(value, &value_filter); + value_filter.MergeFrom(filter); + return value_filter.SerializeAsString() == filter.SerializeAsString(); +} diff --git a/chrome/test/sync/engine/mock_server_connection.h b/chrome/test/sync/engine/mock_server_connection.h index 07c9ca6..dc9af6f 100755 --- a/chrome/test/sync/engine/mock_server_connection.h +++ b/chrome/test/sync/engine/mock_server_connection.h @@ -7,17 +7,16 @@ #ifndef CHROME_TEST_SYNC_ENGINE_MOCK_SERVER_CONNECTION_H_ #define CHROME_TEST_SYNC_ENGINE_MOCK_SERVER_CONNECTION_H_ +#include <bitset> #include <string> #include <vector> #include "chrome/browser/sync/engine/net/server_connection_manager.h" #include "chrome/browser/sync/protocol/sync.pb.h" #include "chrome/browser/sync/syncable/directory_manager.h" +#include "chrome/browser/sync/syncable/model_type.h" #include "chrome/browser/sync/util/closure.h" -using std::string; -using std::vector; - namespace syncable { class DirectoryManager; class ScopedDirLookup; @@ -136,8 +135,10 @@ class MockConnectionManager : public browser_sync::ServerConnectionManager { sync_pb::ClientCommand* GetNextClientCommand(); - const vector<syncable::Id>& committed_ids() const { return committed_ids_; } - const vector<sync_pb::CommitMessage*>& commit_messages() const { + const std::vector<syncable::Id>& committed_ids() const { + return committed_ids_; + } + const std::vector<sync_pb::CommitMessage*>& commit_messages() const { return commit_messages_; } // Retrieve the last sent commit message. @@ -157,6 +158,23 @@ class MockConnectionManager : public browser_sync::ServerConnectionManager { use_legacy_bookmarks_protocol_ = value; } + // Retrieve the number of GetUpdates requests that the mock server has + // seen since the last time this function was called. Can be used to + // verify that a GetUpdates actually did or did not happen after running + // the syncer. + int GetAndClearNumGetUpdatesRequests() { + int result = num_get_updates_requests_; + num_get_updates_requests_ = 0; + return result; + } + + // Expect that GetUpdates will request exactly the types indicated in + // the bitset. + void ExpectGetUpdatesRequestTypes( + std::bitset<syncable::MODEL_TYPE_COUNT> expected_filter) { + expected_filter_ = expected_filter; + } + private: sync_pb::SyncEntity* AddUpdateFull(syncable::Id id, syncable::Id parentid, string name, int64 version, @@ -189,15 +207,21 @@ class MockConnectionManager : public browser_sync::ServerConnectionManager { return next_position_in_parent_--; } + // Determine whether an EntitySpecifics filter (like that sent in + // GetUpdates.requested_types) indicates that a particular ModelType + // should be included. + bool IsModelTypePresentInSpecifics(const sync_pb::EntitySpecifics& filter, + syncable::ModelType value); + // All IDs that have been committed. - vector<syncable::Id> committed_ids_; + std::vector<syncable::Id> committed_ids_; // Control of when/if we return conflicts. bool conflict_all_commits_; int conflict_n_commits_; // Commit messages we've sent - vector<sync_pb::CommitMessage*> commit_messages_; + std::vector<sync_pb::CommitMessage*> commit_messages_; // The next id the mock will return to a commit. int next_new_id_; @@ -249,6 +273,10 @@ class MockConnectionManager : public browser_sync::ServerConnectionManager { // use the older sync_pb::SyncEntity_BookmarkData-style protocol. bool use_legacy_bookmarks_protocol_; + std::bitset<syncable::MODEL_TYPE_COUNT> expected_filter_; + + int num_get_updates_requests_; + DISALLOW_COPY_AND_ASSIGN(MockConnectionManager); }; diff --git a/chrome/test/sync/engine/proto_extension_validator.h b/chrome/test/sync/engine/proto_extension_validator.h new file mode 100755 index 0000000..b4246d7 --- /dev/null +++ b/chrome/test/sync/engine/proto_extension_validator.h @@ -0,0 +1,56 @@ +// Copyright (c) 2010 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. + +// A test utility that makes it easy to assert the exact presence of +// protobuf extensions in an extensible message. Example code: +// +// sync_pb::EntitySpecifics value; // Set up a test value. +// value.MutableExtension(sync_pb::bookmark); +// +// ProtoExtensionValidator<sync_pb::EntitySpecifics> good_expectation(value); +// good_expectation.ExpectHasExtension(sync_pb::bookmark); +// good_expectation.ExpectHasNoOtherFieldsOrExtensions(); +// +// ProtoExtensionValidator<sync_pb::EntitySpecifics> bad_expectation(value); +// bad_expectation.ExpectHasExtension(sync_pb::preference); // Fails, no pref +// bad_expectation.ExpectHasNoOtherFieldsOrExtensions(); // Fails, bookmark + +#ifndef CHROME_TEST_SYNC_ENGINE_PROTO_EXTENSION_VALIDATOR_H_ +#define CHROME_TEST_SYNC_ENGINE_PROTO_EXTENSION_VALIDATOR_H_ + +#include <vector> + +#include "base/string_util.h" +#include "chrome/test/sync/engine/syncer_command_test.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace browser_sync { + +template<typename MessageType> +class ProtoExtensionValidator { + public: + explicit ProtoExtensionValidator(const MessageType& proto) + : proto_(proto) { + } + template<typename ExtensionTokenType> + void ExpectHasExtension(ExtensionTokenType token) { + EXPECT_TRUE(proto_.HasExtension(token)) + << "Proto failed to contain expected extension"; + proto_.ClearExtension(token); + EXPECT_FALSE(proto_.HasExtension(token)); + } + void ExpectNoOtherFieldsOrExtensions() { + EXPECT_EQ(MessageType::default_instance().SerializeAsString(), + proto_.SerializeAsString()) + << "Proto contained additional unexpected extensions."; + } + + private: + MessageType proto_; + DISALLOW_COPY_AND_ASSIGN(ProtoExtensionValidator); +}; + +} // namespace browser_sync + +#endif // CHROME_TEST_SYNC_ENGINE_PROTO_EXTENSION_VALIDATOR_H_ |