| 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 #include "sync/engine/syncer_proto_util.h" | |
| 6 | |
| 7 #include <string> | |
| 8 | |
| 9 #include "base/compiler_specific.h" | |
| 10 #include "base/message_loop/message_loop.h" | |
| 11 #include "base/time/time.h" | |
| 12 #include "sync/internal_api/public/base/cancelation_signal.h" | |
| 13 #include "sync/internal_api/public/base/model_type_test_util.h" | |
| 14 #include "sync/protocol/bookmark_specifics.pb.h" | |
| 15 #include "sync/protocol/password_specifics.pb.h" | |
| 16 #include "sync/protocol/sync.pb.h" | |
| 17 #include "sync/protocol/sync_enums.pb.h" | |
| 18 #include "sync/sessions/sync_session_context.h" | |
| 19 #include "sync/syncable/directory.h" | |
| 20 #include "sync/test/engine/mock_connection_manager.h" | |
| 21 #include "sync/test/engine/test_directory_setter_upper.h" | |
| 22 #include "testing/gtest/include/gtest/gtest.h" | |
| 23 | |
| 24 using ::testing::_; | |
| 25 | |
| 26 using sync_pb::ClientToServerMessage; | |
| 27 using sync_pb::CommitResponse_EntryResponse; | |
| 28 using sync_pb::SyncEntity; | |
| 29 | |
| 30 namespace syncer { | |
| 31 | |
| 32 using sessions::SyncSessionContext; | |
| 33 | |
| 34 class MockDelegate : public sessions::SyncSession::Delegate { | |
| 35 public: | |
| 36 MockDelegate() {} | |
| 37 ~MockDelegate() {} | |
| 38 | |
| 39 MOCK_METHOD1(OnReceivedShortPollIntervalUpdate, void(const base::TimeDelta&)); | |
| 40 MOCK_METHOD1(OnReceivedLongPollIntervalUpdate, void(const base::TimeDelta&)); | |
| 41 MOCK_METHOD1(OnReceivedSessionsCommitDelay, void(const base::TimeDelta&)); | |
| 42 MOCK_METHOD1(OnReceivedClientInvalidationHintBufferSize, void(int)); | |
| 43 MOCK_METHOD1(OnSyncProtocolError, void(const SyncProtocolError&)); | |
| 44 }; | |
| 45 | |
| 46 // Builds a ClientToServerResponse with some data type ids, including | |
| 47 // invalid ones. GetTypesToMigrate() should return only the valid | |
| 48 // model types. | |
| 49 TEST(SyncerProtoUtil, GetTypesToMigrate) { | |
| 50 sync_pb::ClientToServerResponse response; | |
| 51 response.add_migrated_data_type_id( | |
| 52 GetSpecificsFieldNumberFromModelType(BOOKMARKS)); | |
| 53 response.add_migrated_data_type_id( | |
| 54 GetSpecificsFieldNumberFromModelType(HISTORY_DELETE_DIRECTIVES)); | |
| 55 response.add_migrated_data_type_id(-1); | |
| 56 EXPECT_EQ(ModelTypeSet(BOOKMARKS, HISTORY_DELETE_DIRECTIVES), | |
| 57 GetTypesToMigrate(response)); | |
| 58 } | |
| 59 | |
| 60 // Builds a ClientToServerResponse_Error with some error data type | |
| 61 // ids, including invalid ones. ConvertErrorPBToSyncProtocolError() should | |
| 62 // return a SyncProtocolError with only the valid model types. | |
| 63 TEST(SyncerProtoUtil, ConvertErrorPBToSyncProtocolError) { | |
| 64 sync_pb::ClientToServerResponse_Error error_pb; | |
| 65 error_pb.set_error_type(sync_pb::SyncEnums::THROTTLED); | |
| 66 error_pb.add_error_data_type_ids( | |
| 67 GetSpecificsFieldNumberFromModelType(BOOKMARKS)); | |
| 68 error_pb.add_error_data_type_ids( | |
| 69 GetSpecificsFieldNumberFromModelType(HISTORY_DELETE_DIRECTIVES)); | |
| 70 error_pb.add_error_data_type_ids(-1); | |
| 71 SyncProtocolError error = ConvertErrorPBToSyncProtocolError(error_pb); | |
| 72 EXPECT_EQ(ModelTypeSet(BOOKMARKS, HISTORY_DELETE_DIRECTIVES), | |
| 73 error.error_data_types); | |
| 74 } | |
| 75 | |
| 76 // Tests NameFromSyncEntity and NameFromCommitEntryResponse when only the name | |
| 77 // field is provided. | |
| 78 TEST(SyncerProtoUtil, NameExtractionOneName) { | |
| 79 SyncEntity one_name_entity; | |
| 80 CommitResponse_EntryResponse one_name_response; | |
| 81 | |
| 82 const std::string one_name_string("Eggheadednesses"); | |
| 83 one_name_entity.set_name(one_name_string); | |
| 84 one_name_response.set_name(one_name_string); | |
| 85 | |
| 86 const std::string name_a = | |
| 87 SyncerProtoUtil::NameFromSyncEntity(one_name_entity); | |
| 88 EXPECT_EQ(one_name_string, name_a); | |
| 89 } | |
| 90 | |
| 91 TEST(SyncerProtoUtil, NameExtractionOneUniqueName) { | |
| 92 SyncEntity one_name_entity; | |
| 93 CommitResponse_EntryResponse one_name_response; | |
| 94 | |
| 95 const std::string one_name_string("Eggheadednesses"); | |
| 96 | |
| 97 one_name_entity.set_non_unique_name(one_name_string); | |
| 98 one_name_response.set_non_unique_name(one_name_string); | |
| 99 | |
| 100 const std::string name_a = | |
| 101 SyncerProtoUtil::NameFromSyncEntity(one_name_entity); | |
| 102 EXPECT_EQ(one_name_string, name_a); | |
| 103 } | |
| 104 | |
| 105 // Tests NameFromSyncEntity and NameFromCommitEntryResponse when both the name | |
| 106 // field and the non_unique_name fields are provided. | |
| 107 // Should prioritize non_unique_name. | |
| 108 TEST(SyncerProtoUtil, NameExtractionTwoNames) { | |
| 109 SyncEntity two_name_entity; | |
| 110 CommitResponse_EntryResponse two_name_response; | |
| 111 | |
| 112 const std::string neuro("Neuroanatomists"); | |
| 113 const std::string oxyphen("Oxyphenbutazone"); | |
| 114 | |
| 115 two_name_entity.set_name(oxyphen); | |
| 116 two_name_entity.set_non_unique_name(neuro); | |
| 117 | |
| 118 two_name_response.set_name(oxyphen); | |
| 119 two_name_response.set_non_unique_name(neuro); | |
| 120 | |
| 121 const std::string name_a = | |
| 122 SyncerProtoUtil::NameFromSyncEntity(two_name_entity); | |
| 123 EXPECT_EQ(neuro, name_a); | |
| 124 } | |
| 125 | |
| 126 class SyncerProtoUtilTest : public testing::Test { | |
| 127 public: | |
| 128 void SetUp() override { dir_maker_.SetUp(); } | |
| 129 | |
| 130 void TearDown() override { dir_maker_.TearDown(); } | |
| 131 | |
| 132 syncable::Directory* directory() { | |
| 133 return dir_maker_.directory(); | |
| 134 } | |
| 135 | |
| 136 // Helper function to call GetProtocolErrorFromResponse. Allows not adding | |
| 137 // individual tests as friends to SyncerProtoUtil. | |
| 138 static SyncProtocolError CallGetProtocolErrorFromResponse( | |
| 139 const sync_pb::ClientToServerResponse& response, | |
| 140 syncable::Directory* directory) { | |
| 141 return SyncerProtoUtil::GetProtocolErrorFromResponse(response, directory); | |
| 142 } | |
| 143 | |
| 144 protected: | |
| 145 base::MessageLoop message_loop_; | |
| 146 TestDirectorySetterUpper dir_maker_; | |
| 147 }; | |
| 148 | |
| 149 TEST_F(SyncerProtoUtilTest, VerifyResponseBirthday) { | |
| 150 // Both sides empty | |
| 151 EXPECT_TRUE(directory()->store_birthday().empty()); | |
| 152 sync_pb::ClientToServerResponse response; | |
| 153 SyncProtocolError sync_protocol_error; | |
| 154 response.set_error_code(sync_pb::SyncEnums::SUCCESS); | |
| 155 | |
| 156 sync_protocol_error = CallGetProtocolErrorFromResponse(response, directory()); | |
| 157 EXPECT_EQ(NOT_MY_BIRTHDAY, sync_protocol_error.error_type); | |
| 158 EXPECT_EQ(DISABLE_SYNC_ON_CLIENT, sync_protocol_error.action); | |
| 159 | |
| 160 // Remote set, local empty | |
| 161 response.set_store_birthday("flan"); | |
| 162 sync_protocol_error = CallGetProtocolErrorFromResponse(response, directory()); | |
| 163 EXPECT_EQ(SYNC_SUCCESS, sync_protocol_error.error_type); | |
| 164 EXPECT_EQ(UNKNOWN_ACTION, sync_protocol_error.action); | |
| 165 EXPECT_EQ(directory()->store_birthday(), "flan"); | |
| 166 | |
| 167 // Remote empty, local set. | |
| 168 response.clear_store_birthday(); | |
| 169 sync_protocol_error = CallGetProtocolErrorFromResponse(response, directory()); | |
| 170 EXPECT_EQ(SYNC_SUCCESS, sync_protocol_error.error_type); | |
| 171 EXPECT_EQ(UNKNOWN_ACTION, sync_protocol_error.action); | |
| 172 EXPECT_EQ(directory()->store_birthday(), "flan"); | |
| 173 | |
| 174 // Doesn't match | |
| 175 response.set_store_birthday("meat"); | |
| 176 response.set_error_code(sync_pb::SyncEnums::NOT_MY_BIRTHDAY); | |
| 177 sync_protocol_error = CallGetProtocolErrorFromResponse(response, directory()); | |
| 178 EXPECT_EQ(NOT_MY_BIRTHDAY, sync_protocol_error.error_type); | |
| 179 EXPECT_EQ(DISABLE_SYNC_ON_CLIENT, sync_protocol_error.action); | |
| 180 | |
| 181 // Doesn't match. CLIENT_DATA_OBSOLETE error is set. | |
| 182 response.set_error_code(sync_pb::SyncEnums::CLIENT_DATA_OBSOLETE); | |
| 183 sync_protocol_error = CallGetProtocolErrorFromResponse(response, directory()); | |
| 184 EXPECT_EQ(CLIENT_DATA_OBSOLETE, sync_protocol_error.error_type); | |
| 185 EXPECT_EQ(RESET_LOCAL_SYNC_DATA, sync_protocol_error.action); | |
| 186 } | |
| 187 | |
| 188 TEST_F(SyncerProtoUtilTest, VerifyDisabledByAdmin) { | |
| 189 // No error code | |
| 190 sync_pb::ClientToServerResponse response; | |
| 191 SyncProtocolError sync_protocol_error; | |
| 192 directory()->set_store_birthday("flan"); | |
| 193 response.set_error_code(sync_pb::SyncEnums::SUCCESS); | |
| 194 | |
| 195 sync_protocol_error = CallGetProtocolErrorFromResponse(response, directory()); | |
| 196 EXPECT_EQ(SYNC_SUCCESS, sync_protocol_error.error_type); | |
| 197 EXPECT_EQ(UNKNOWN_ACTION, sync_protocol_error.action); | |
| 198 | |
| 199 // Has error code, but not disabled | |
| 200 response.set_error_code(sync_pb::SyncEnums::NOT_MY_BIRTHDAY); | |
| 201 sync_protocol_error = CallGetProtocolErrorFromResponse(response, directory()); | |
| 202 EXPECT_EQ(NOT_MY_BIRTHDAY, sync_protocol_error.error_type); | |
| 203 EXPECT_NE(UNKNOWN_ACTION, sync_protocol_error.action); | |
| 204 | |
| 205 // Has error code, and is disabled by admin | |
| 206 response.set_error_code(sync_pb::SyncEnums::DISABLED_BY_ADMIN); | |
| 207 sync_protocol_error = CallGetProtocolErrorFromResponse(response, directory()); | |
| 208 EXPECT_EQ(DISABLED_BY_ADMIN, sync_protocol_error.error_type); | |
| 209 EXPECT_EQ(STOP_SYNC_FOR_DISABLED_ACCOUNT, sync_protocol_error.action); | |
| 210 } | |
| 211 | |
| 212 TEST_F(SyncerProtoUtilTest, AddRequestBirthday) { | |
| 213 EXPECT_TRUE(directory()->store_birthday().empty()); | |
| 214 ClientToServerMessage msg; | |
| 215 SyncerProtoUtil::AddRequestBirthday(directory(), &msg); | |
| 216 EXPECT_FALSE(msg.has_store_birthday()); | |
| 217 | |
| 218 directory()->set_store_birthday("meat"); | |
| 219 SyncerProtoUtil::AddRequestBirthday(directory(), &msg); | |
| 220 EXPECT_EQ(msg.store_birthday(), "meat"); | |
| 221 } | |
| 222 | |
| 223 class DummyConnectionManager : public ServerConnectionManager { | |
| 224 public: | |
| 225 explicit DummyConnectionManager(CancelationSignal* signal) | |
| 226 : ServerConnectionManager("unused", 0, false, signal), | |
| 227 send_error_(false) {} | |
| 228 | |
| 229 ~DummyConnectionManager() override {} | |
| 230 bool PostBufferWithCachedAuth(PostBufferParams* params) override { | |
| 231 if (send_error_) { | |
| 232 return false; | |
| 233 } | |
| 234 | |
| 235 sync_pb::ClientToServerResponse response; | |
| 236 response.SerializeToString(¶ms->buffer_out); | |
| 237 | |
| 238 return true; | |
| 239 } | |
| 240 | |
| 241 void set_send_error(bool send) { | |
| 242 send_error_ = send; | |
| 243 } | |
| 244 | |
| 245 private: | |
| 246 bool send_error_; | |
| 247 }; | |
| 248 | |
| 249 TEST_F(SyncerProtoUtilTest, PostAndProcessHeaders) { | |
| 250 CancelationSignal signal; | |
| 251 DummyConnectionManager dcm(&signal); | |
| 252 ClientToServerMessage msg; | |
| 253 SyncerProtoUtil::SetProtocolVersion(&msg); | |
| 254 msg.set_share("required"); | |
| 255 msg.set_message_contents(ClientToServerMessage::GET_UPDATES); | |
| 256 sync_pb::ClientToServerResponse response; | |
| 257 | |
| 258 dcm.set_send_error(true); | |
| 259 EXPECT_FALSE(SyncerProtoUtil::PostAndProcessHeaders(&dcm, NULL, | |
| 260 msg, &response)); | |
| 261 | |
| 262 dcm.set_send_error(false); | |
| 263 EXPECT_TRUE(SyncerProtoUtil::PostAndProcessHeaders(&dcm, NULL, | |
| 264 msg, &response)); | |
| 265 } | |
| 266 | |
| 267 } // namespace syncer | |
| OLD | NEW |