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