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.
5 #include "sync/engine/syncer_proto_util.h"
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"
28 using sync_pb::ClientToServerMessage
;
29 using sync_pb::CommitResponse_EntryResponse
;
30 using sync_pb::SyncEntity
;
34 using sessions::SyncSessionContext
;
37 class MockDelegate
: public sessions::SyncSession::Delegate
{
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
&));
49 // Builds a ClientToServerResponse with some data type ids, including
50 // invalid ones. GetTypesToMigrate() should return only the valid
52 TEST(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);
60 GetTypesToMigrate(response
).Equals(
61 ModelTypeSet(BOOKMARKS
, HISTORY_DELETE_DIRECTIVES
)));
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.
67 TEST(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
);
77 error
.error_data_types
.Equals(
78 ModelTypeSet(BOOKMARKS
, HISTORY_DELETE_DIRECTIVES
)));
81 TEST(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};
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
]);
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
));
101 EXPECT_TRUE(SyncerProtoUtil::ProtoBytesEqualsBlob(test_message1
,
103 EXPECT_FALSE(SyncerProtoUtil::ProtoBytesEqualsBlob(test_message1
,
105 EXPECT_FALSE(SyncerProtoUtil::ProtoBytesEqualsBlob(test_message1
,
107 EXPECT_FALSE(SyncerProtoUtil::ProtoBytesEqualsBlob(test_message2
,
109 EXPECT_TRUE(SyncerProtoUtil::ProtoBytesEqualsBlob(test_message2
,
111 EXPECT_FALSE(SyncerProtoUtil::ProtoBytesEqualsBlob(test_message2
,
113 EXPECT_FALSE(SyncerProtoUtil::ProtoBytesEqualsBlob(test_message3
,
115 EXPECT_FALSE(SyncerProtoUtil::ProtoBytesEqualsBlob(test_message3
,
117 EXPECT_TRUE(SyncerProtoUtil::ProtoBytesEqualsBlob(test_message3
,
121 EXPECT_FALSE(SyncerProtoUtil::ProtoBytesEqualsBlob(test_message1
,
123 SyncerProtoUtil::CopyProtoBytesIntoBlob(test_message1
, &blob1_copy
);
124 EXPECT_TRUE(SyncerProtoUtil::ProtoBytesEqualsBlob(test_message1
,
127 std::string message2_copy
;
128 EXPECT_FALSE(SyncerProtoUtil::ProtoBytesEqualsBlob(message2_copy
,
130 SyncerProtoUtil::CopyBlobIntoProtoBytes(test_blob2
, &message2_copy
);
131 EXPECT_TRUE(SyncerProtoUtil::ProtoBytesEqualsBlob(message2_copy
,
135 // Tests NameFromSyncEntity and NameFromCommitEntryResponse when only the name
136 // field is provided.
137 TEST(SyncerProtoUtil
, NameExtractionOneName
) {
138 SyncEntity one_name_entity
;
139 CommitResponse_EntryResponse one_name_response
;
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
);
145 const std::string name_a
=
146 SyncerProtoUtil::NameFromSyncEntity(one_name_entity
);
147 EXPECT_EQ(one_name_string
, name_a
);
150 TEST(SyncerProtoUtil
, NameExtractionOneUniqueName
) {
151 SyncEntity one_name_entity
;
152 CommitResponse_EntryResponse one_name_response
;
154 const std::string
one_name_string("Eggheadednesses");
156 one_name_entity
.set_non_unique_name(one_name_string
);
157 one_name_response
.set_non_unique_name(one_name_string
);
159 const std::string name_a
=
160 SyncerProtoUtil::NameFromSyncEntity(one_name_entity
);
161 EXPECT_EQ(one_name_string
, name_a
);
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.
167 TEST(SyncerProtoUtil
, NameExtractionTwoNames
) {
168 SyncEntity two_name_entity
;
169 CommitResponse_EntryResponse two_name_response
;
171 const std::string
neuro("Neuroanatomists");
172 const std::string
oxyphen("Oxyphenbutazone");
174 two_name_entity
.set_name(oxyphen
);
175 two_name_entity
.set_non_unique_name(neuro
);
177 two_name_response
.set_name(oxyphen
);
178 two_name_response
.set_non_unique_name(neuro
);
180 const std::string name_a
=
181 SyncerProtoUtil::NameFromSyncEntity(two_name_entity
);
182 EXPECT_EQ(neuro
, name_a
);
185 class SyncerProtoUtilTest
: public testing::Test
{
187 void SetUp() override
{ dir_maker_
.SetUp(); }
189 void TearDown() override
{ dir_maker_
.TearDown(); }
191 syncable::Directory
* directory() {
192 return dir_maker_
.directory();
196 base::MessageLoop message_loop_
;
197 TestDirectorySetterUpper dir_maker_
;
200 TEST_F(SyncerProtoUtilTest
, VerifyResponseBirthday
) {
202 EXPECT_TRUE(directory()->store_birthday().empty());
203 sync_pb::ClientToServerResponse response
;
204 EXPECT_FALSE(SyncerProtoUtil::VerifyResponseBirthday(response
, directory()));
206 // Remote set, local empty
207 response
.set_store_birthday("flan");
208 EXPECT_TRUE(SyncerProtoUtil::VerifyResponseBirthday(response
, directory()));
209 EXPECT_EQ(directory()->store_birthday(), "flan");
211 // Remote empty, local set.
212 response
.clear_store_birthday();
213 EXPECT_TRUE(SyncerProtoUtil::VerifyResponseBirthday(response
, directory()));
214 EXPECT_EQ(directory()->store_birthday(), "flan");
217 response
.set_store_birthday("meat");
218 EXPECT_FALSE(SyncerProtoUtil::VerifyResponseBirthday(response
, directory()));
220 response
.set_error_code(sync_pb::SyncEnums::CLEAR_PENDING
);
221 EXPECT_FALSE(SyncerProtoUtil::VerifyResponseBirthday(response
, directory()));
224 TEST_F(SyncerProtoUtilTest
, VerifyDisabledByAdmin
) {
226 sync_pb::ClientToServerResponse response
;
227 EXPECT_FALSE(SyncerProtoUtil::IsSyncDisabledByAdmin(response
));
229 // Has error code, but not disabled
230 response
.set_error_code(sync_pb::SyncEnums::NOT_MY_BIRTHDAY
);
231 EXPECT_FALSE(SyncerProtoUtil::IsSyncDisabledByAdmin(response
));
233 // Has error code, and is disabled by admin
234 response
.set_error_code(sync_pb::SyncEnums::DISABLED_BY_ADMIN
);
235 EXPECT_TRUE(SyncerProtoUtil::IsSyncDisabledByAdmin(response
));
238 TEST_F(SyncerProtoUtilTest
, AddRequestBirthday
) {
239 EXPECT_TRUE(directory()->store_birthday().empty());
240 ClientToServerMessage msg
;
241 SyncerProtoUtil::AddRequestBirthday(directory(), &msg
);
242 EXPECT_FALSE(msg
.has_store_birthday());
244 directory()->set_store_birthday("meat");
245 SyncerProtoUtil::AddRequestBirthday(directory(), &msg
);
246 EXPECT_EQ(msg
.store_birthday(), "meat");
249 class DummyConnectionManager
: public ServerConnectionManager
{
251 DummyConnectionManager(CancelationSignal
* signal
)
252 : ServerConnectionManager("unused", 0, false, signal
),
254 access_denied_(false) {}
256 ~DummyConnectionManager() override
{}
257 bool PostBufferWithCachedAuth(PostBufferParams
* params
,
258 ScopedServerStatusWatcher
* watcher
) override
{
263 sync_pb::ClientToServerResponse response
;
264 if (access_denied_
) {
265 response
.set_error_code(sync_pb::SyncEnums::ACCESS_DENIED
);
267 response
.SerializeToString(¶ms
->buffer_out
);
272 void set_send_error(bool send
) {
276 void set_access_denied(bool denied
) {
277 access_denied_
= denied
;
285 TEST_F(SyncerProtoUtilTest
, PostAndProcessHeaders
) {
286 CancelationSignal signal
;
287 DummyConnectionManager
dcm(&signal
);
288 ClientToServerMessage msg
;
289 SyncerProtoUtil::SetProtocolVersion(&msg
);
290 msg
.set_share("required");
291 msg
.set_message_contents(ClientToServerMessage::GET_UPDATES
);
292 sync_pb::ClientToServerResponse response
;
294 dcm
.set_send_error(true);
295 EXPECT_FALSE(SyncerProtoUtil::PostAndProcessHeaders(&dcm
, NULL
,
298 dcm
.set_send_error(false);
299 EXPECT_TRUE(SyncerProtoUtil::PostAndProcessHeaders(&dcm
, NULL
,
302 dcm
.set_access_denied(true);
303 EXPECT_FALSE(SyncerProtoUtil::PostAndProcessHeaders(&dcm
, NULL
,
307 } // namespace syncer