syncer_proto_util_unittest.cc revision effb81e5f8246d0db0270817048dc992db66e9fb
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#include "sync/engine/syncer_proto_util.h" 6 7#include <string> 8 9#include "base/basictypes.h" 10#include "base/compiler_specific.h" 11#include "base/message_loop/message_loop.h" 12#include "base/time/time.h" 13#include "sync/internal_api/public/base/cancelation_signal.h" 14#include "sync/internal_api/public/base/model_type_test_util.h" 15#include "sync/protocol/bookmark_specifics.pb.h" 16#include "sync/protocol/password_specifics.pb.h" 17#include "sync/protocol/sync.pb.h" 18#include "sync/protocol/sync_enums.pb.h" 19#include "sync/sessions/sync_session_context.h" 20#include "sync/syncable/blob.h" 21#include "sync/syncable/directory.h" 22#include "sync/test/engine/mock_connection_manager.h" 23#include "sync/test/engine/test_directory_setter_upper.h" 24#include "testing/gtest/include/gtest/gtest.h" 25 26using ::testing::_; 27 28using sync_pb::ClientToServerMessage; 29using sync_pb::CommitResponse_EntryResponse; 30using sync_pb::SyncEntity; 31 32namespace syncer { 33 34using sessions::SyncSessionContext; 35using syncable::Blob; 36 37class MockDelegate : public sessions::SyncSession::Delegate { 38 public: 39 MockDelegate() {} 40 ~MockDelegate() {} 41 42 MOCK_METHOD1(OnReceivedShortPollIntervalUpdate, void(const base::TimeDelta&)); 43 MOCK_METHOD1(OnReceivedLongPollIntervalUpdate ,void(const base::TimeDelta&)); 44 MOCK_METHOD1(OnReceivedSessionsCommitDelay, void(const base::TimeDelta&)); 45 MOCK_METHOD1(OnReceivedClientInvalidationHintBufferSize, void(int)); 46 MOCK_METHOD1(OnSyncProtocolError, void(const SyncProtocolError&)); 47}; 48 49// Builds a ClientToServerResponse with some data type ids, including 50// invalid ones. GetTypesToMigrate() should return only the valid 51// model types. 52TEST(SyncerProtoUtil, GetTypesToMigrate) { 53 sync_pb::ClientToServerResponse response; 54 response.add_migrated_data_type_id( 55 GetSpecificsFieldNumberFromModelType(BOOKMARKS)); 56 response.add_migrated_data_type_id( 57 GetSpecificsFieldNumberFromModelType(HISTORY_DELETE_DIRECTIVES)); 58 response.add_migrated_data_type_id(-1); 59 EXPECT_TRUE( 60 GetTypesToMigrate(response).Equals( 61 ModelTypeSet(BOOKMARKS, HISTORY_DELETE_DIRECTIVES))); 62} 63 64// Builds a ClientToServerResponse_Error with some error data type 65// ids, including invalid ones. ConvertErrorPBToLocalType() should 66// return a SyncProtocolError with only the valid model types. 67TEST(SyncerProtoUtil, ConvertErrorPBToLocalType) { 68 sync_pb::ClientToServerResponse_Error error_pb; 69 error_pb.set_error_type(sync_pb::SyncEnums::THROTTLED); 70 error_pb.add_error_data_type_ids( 71 GetSpecificsFieldNumberFromModelType(BOOKMARKS)); 72 error_pb.add_error_data_type_ids( 73 GetSpecificsFieldNumberFromModelType(HISTORY_DELETE_DIRECTIVES)); 74 error_pb.add_error_data_type_ids(-1); 75 SyncProtocolError error = ConvertErrorPBToLocalType(error_pb); 76 EXPECT_TRUE( 77 error.error_data_types.Equals( 78 ModelTypeSet(BOOKMARKS, HISTORY_DELETE_DIRECTIVES))); 79} 80 81TEST(SyncerProtoUtil, TestBlobToProtocolBufferBytesUtilityFunctions) { 82 unsigned char test_data1[] = {1, 2, 3, 4, 5, 6, 7, 8, 0, 1, 4, 2, 9}; 83 unsigned char test_data2[] = {1, 99, 3, 4, 5, 6, 7, 8, 0, 1, 4, 2, 9}; 84 unsigned char test_data3[] = {99, 2, 3, 4, 5, 6, 7, 8}; 85 86 syncable::Blob test_blob1, test_blob2, test_blob3; 87 for (size_t i = 0; i < arraysize(test_data1); ++i) 88 test_blob1.push_back(test_data1[i]); 89 for (size_t i = 0; i < arraysize(test_data2); ++i) 90 test_blob2.push_back(test_data2[i]); 91 for (size_t i = 0; i < arraysize(test_data3); ++i) 92 test_blob3.push_back(test_data3[i]); 93 94 std::string test_message1(reinterpret_cast<char*>(test_data1), 95 arraysize(test_data1)); 96 std::string test_message2(reinterpret_cast<char*>(test_data2), 97 arraysize(test_data2)); 98 std::string test_message3(reinterpret_cast<char*>(test_data3), 99 arraysize(test_data3)); 100 101 EXPECT_TRUE(SyncerProtoUtil::ProtoBytesEqualsBlob(test_message1, 102 test_blob1)); 103 EXPECT_FALSE(SyncerProtoUtil::ProtoBytesEqualsBlob(test_message1, 104 test_blob2)); 105 EXPECT_FALSE(SyncerProtoUtil::ProtoBytesEqualsBlob(test_message1, 106 test_blob3)); 107 EXPECT_FALSE(SyncerProtoUtil::ProtoBytesEqualsBlob(test_message2, 108 test_blob1)); 109 EXPECT_TRUE(SyncerProtoUtil::ProtoBytesEqualsBlob(test_message2, 110 test_blob2)); 111 EXPECT_FALSE(SyncerProtoUtil::ProtoBytesEqualsBlob(test_message2, 112 test_blob3)); 113 EXPECT_FALSE(SyncerProtoUtil::ProtoBytesEqualsBlob(test_message3, 114 test_blob1)); 115 EXPECT_FALSE(SyncerProtoUtil::ProtoBytesEqualsBlob(test_message3, 116 test_blob2)); 117 EXPECT_TRUE(SyncerProtoUtil::ProtoBytesEqualsBlob(test_message3, 118 test_blob3)); 119 120 Blob blob1_copy; 121 EXPECT_FALSE(SyncerProtoUtil::ProtoBytesEqualsBlob(test_message1, 122 blob1_copy)); 123 SyncerProtoUtil::CopyProtoBytesIntoBlob(test_message1, &blob1_copy); 124 EXPECT_TRUE(SyncerProtoUtil::ProtoBytesEqualsBlob(test_message1, 125 blob1_copy)); 126 127 std::string message2_copy; 128 EXPECT_FALSE(SyncerProtoUtil::ProtoBytesEqualsBlob(message2_copy, 129 test_blob2)); 130 SyncerProtoUtil::CopyBlobIntoProtoBytes(test_blob2, &message2_copy); 131 EXPECT_TRUE(SyncerProtoUtil::ProtoBytesEqualsBlob(message2_copy, 132 test_blob2)); 133} 134 135// Tests NameFromSyncEntity and NameFromCommitEntryResponse when only the name 136// field is provided. 137TEST(SyncerProtoUtil, NameExtractionOneName) { 138 SyncEntity one_name_entity; 139 CommitResponse_EntryResponse one_name_response; 140 141 const std::string one_name_string("Eggheadednesses"); 142 one_name_entity.set_name(one_name_string); 143 one_name_response.set_name(one_name_string); 144 145 const std::string name_a = 146 SyncerProtoUtil::NameFromSyncEntity(one_name_entity); 147 EXPECT_EQ(one_name_string, name_a); 148} 149 150TEST(SyncerProtoUtil, NameExtractionOneUniqueName) { 151 SyncEntity one_name_entity; 152 CommitResponse_EntryResponse one_name_response; 153 154 const std::string one_name_string("Eggheadednesses"); 155 156 one_name_entity.set_non_unique_name(one_name_string); 157 one_name_response.set_non_unique_name(one_name_string); 158 159 const std::string name_a = 160 SyncerProtoUtil::NameFromSyncEntity(one_name_entity); 161 EXPECT_EQ(one_name_string, name_a); 162} 163 164// Tests NameFromSyncEntity and NameFromCommitEntryResponse when both the name 165// field and the non_unique_name fields are provided. 166// Should prioritize non_unique_name. 167TEST(SyncerProtoUtil, NameExtractionTwoNames) { 168 SyncEntity two_name_entity; 169 CommitResponse_EntryResponse two_name_response; 170 171 const std::string neuro("Neuroanatomists"); 172 const std::string oxyphen("Oxyphenbutazone"); 173 174 two_name_entity.set_name(oxyphen); 175 two_name_entity.set_non_unique_name(neuro); 176 177 two_name_response.set_name(oxyphen); 178 two_name_response.set_non_unique_name(neuro); 179 180 const std::string name_a = 181 SyncerProtoUtil::NameFromSyncEntity(two_name_entity); 182 EXPECT_EQ(neuro, name_a); 183} 184 185class SyncerProtoUtilTest : public testing::Test { 186 public: 187 virtual void SetUp() { 188 dir_maker_.SetUp(); 189 } 190 191 virtual void TearDown() { 192 dir_maker_.TearDown(); 193 } 194 195 syncable::Directory* directory() { 196 return dir_maker_.directory(); 197 } 198 199 protected: 200 base::MessageLoop message_loop_; 201 TestDirectorySetterUpper dir_maker_; 202}; 203 204TEST_F(SyncerProtoUtilTest, VerifyResponseBirthday) { 205 // Both sides empty 206 EXPECT_TRUE(directory()->store_birthday().empty()); 207 sync_pb::ClientToServerResponse response; 208 EXPECT_FALSE(SyncerProtoUtil::VerifyResponseBirthday(response, directory())); 209 210 // Remote set, local empty 211 response.set_store_birthday("flan"); 212 EXPECT_TRUE(SyncerProtoUtil::VerifyResponseBirthday(response, directory())); 213 EXPECT_EQ(directory()->store_birthday(), "flan"); 214 215 // Remote empty, local set. 216 response.clear_store_birthday(); 217 EXPECT_TRUE(SyncerProtoUtil::VerifyResponseBirthday(response, directory())); 218 EXPECT_EQ(directory()->store_birthday(), "flan"); 219 220 // Doesn't match 221 response.set_store_birthday("meat"); 222 EXPECT_FALSE(SyncerProtoUtil::VerifyResponseBirthday(response, directory())); 223 224 response.set_error_code(sync_pb::SyncEnums::CLEAR_PENDING); 225 EXPECT_FALSE(SyncerProtoUtil::VerifyResponseBirthday(response, directory())); 226} 227 228TEST_F(SyncerProtoUtilTest, VerifyDisabledByAdmin) { 229 // No error code 230 sync_pb::ClientToServerResponse response; 231 EXPECT_FALSE(SyncerProtoUtil::IsSyncDisabledByAdmin(response)); 232 233 // Has error code, but not disabled 234 response.set_error_code(sync_pb::SyncEnums::NOT_MY_BIRTHDAY); 235 EXPECT_FALSE(SyncerProtoUtil::IsSyncDisabledByAdmin(response)); 236 237 // Has error code, and is disabled by admin 238 response.set_error_code(sync_pb::SyncEnums::DISABLED_BY_ADMIN); 239 EXPECT_TRUE(SyncerProtoUtil::IsSyncDisabledByAdmin(response)); 240} 241 242TEST_F(SyncerProtoUtilTest, AddRequestBirthday) { 243 EXPECT_TRUE(directory()->store_birthday().empty()); 244 ClientToServerMessage msg; 245 SyncerProtoUtil::AddRequestBirthday(directory(), &msg); 246 EXPECT_FALSE(msg.has_store_birthday()); 247 248 directory()->set_store_birthday("meat"); 249 SyncerProtoUtil::AddRequestBirthday(directory(), &msg); 250 EXPECT_EQ(msg.store_birthday(), "meat"); 251} 252 253class DummyConnectionManager : public ServerConnectionManager { 254 public: 255 DummyConnectionManager(CancelationSignal* signal) 256 : ServerConnectionManager("unused", 0, false, signal), 257 send_error_(false), 258 access_denied_(false) {} 259 260 virtual ~DummyConnectionManager() {} 261 virtual bool PostBufferWithCachedAuth( 262 PostBufferParams* params, 263 ScopedServerStatusWatcher* watcher) OVERRIDE { 264 if (send_error_) { 265 return false; 266 } 267 268 sync_pb::ClientToServerResponse response; 269 if (access_denied_) { 270 response.set_error_code(sync_pb::SyncEnums::ACCESS_DENIED); 271 } 272 response.SerializeToString(¶ms->buffer_out); 273 274 return true; 275 } 276 277 void set_send_error(bool send) { 278 send_error_ = send; 279 } 280 281 void set_access_denied(bool denied) { 282 access_denied_ = denied; 283 } 284 285 private: 286 bool send_error_; 287 bool access_denied_; 288}; 289 290TEST_F(SyncerProtoUtilTest, PostAndProcessHeaders) { 291 CancelationSignal signal; 292 DummyConnectionManager dcm(&signal); 293 ClientToServerMessage msg; 294 SyncerProtoUtil::SetProtocolVersion(&msg); 295 msg.set_share("required"); 296 msg.set_message_contents(ClientToServerMessage::GET_UPDATES); 297 sync_pb::ClientToServerResponse response; 298 299 dcm.set_send_error(true); 300 EXPECT_FALSE(SyncerProtoUtil::PostAndProcessHeaders(&dcm, NULL, 301 msg, &response)); 302 303 dcm.set_send_error(false); 304 EXPECT_TRUE(SyncerProtoUtil::PostAndProcessHeaders(&dcm, NULL, 305 msg, &response)); 306 307 dcm.set_access_denied(true); 308 EXPECT_FALSE(SyncerProtoUtil::PostAndProcessHeaders(&dcm, NULL, 309 msg, &response)); 310} 311 312} // namespace syncer 313