• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
26 using ::testing::_;
27 
28 using sync_pb::ClientToServerMessage;
29 using sync_pb::CommitResponse_EntryResponse;
30 using sync_pb::SyncEntity;
31 
32 namespace syncer {
33 
34 using sessions::SyncSessionContext;
35 using syncable::Blob;
36 
37 class MockDelegate : public sessions::SyncSession::Delegate {
38  public:
MockDelegate()39    MockDelegate() {}
~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.
TEST(SyncerProtoUtil,GetTypesToMigrate)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);
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.
TEST(SyncerProtoUtil,ConvertErrorPBToLocalType)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);
76   EXPECT_TRUE(
77       error.error_data_types.Equals(
78           ModelTypeSet(BOOKMARKS, HISTORY_DELETE_DIRECTIVES)));
79 }
80 
TEST(SyncerProtoUtil,TestBlobToProtocolBufferBytesUtilityFunctions)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};
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.
TEST(SyncerProtoUtil,NameExtractionOneName)137 TEST(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 
TEST(SyncerProtoUtil,NameExtractionOneUniqueName)150 TEST(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.
TEST(SyncerProtoUtil,NameExtractionTwoNames)167 TEST(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 
185 class SyncerProtoUtilTest : public testing::Test {
186  public:
SetUp()187   virtual void SetUp() {
188     dir_maker_.SetUp();
189   }
190 
TearDown()191   virtual void TearDown() {
192     dir_maker_.TearDown();
193   }
194 
directory()195   syncable::Directory* directory() {
196     return dir_maker_.directory();
197   }
198 
199  protected:
200   base::MessageLoop message_loop_;
201   TestDirectorySetterUpper dir_maker_;
202 };
203 
TEST_F(SyncerProtoUtilTest,VerifyResponseBirthday)204 TEST_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 
TEST_F(SyncerProtoUtilTest,VerifyDisabledByAdmin)228 TEST_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 
TEST_F(SyncerProtoUtilTest,AddRequestBirthday)242 TEST_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 
253 class DummyConnectionManager : public ServerConnectionManager {
254  public:
DummyConnectionManager(CancelationSignal * signal)255   DummyConnectionManager(CancelationSignal* signal)
256       : ServerConnectionManager("unused", 0, false, signal),
257         send_error_(false),
258         access_denied_(false) {}
259 
~DummyConnectionManager()260   virtual ~DummyConnectionManager() {}
PostBufferWithCachedAuth(PostBufferParams * params,ScopedServerStatusWatcher * watcher)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(&params->buffer_out);
273 
274     return true;
275   }
276 
set_send_error(bool send)277   void set_send_error(bool send) {
278     send_error_ = send;
279   }
280 
set_access_denied(bool denied)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 
TEST_F(SyncerProtoUtilTest,PostAndProcessHeaders)290 TEST_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