- add sources.
[platform/framework/web/crosswalk.git] / src / chrome / browser / sync / glue / generic_change_processor_unittest.cc
1 // Copyright 2013 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 "chrome/browser/sync/glue/generic_change_processor.h"
6
7 #include "base/memory/scoped_ptr.h"
8 #include "base/memory/weak_ptr.h"
9 #include "base/message_loop/message_loop.h"
10 #include "base/strings/stringprintf.h"
11 #include "chrome/browser/sync/glue/data_type_error_handler_mock.h"
12 #include "sync/api/fake_syncable_service.h"
13 #include "sync/api/sync_change.h"
14 #include "sync/api/sync_merge_result.h"
15 #include "sync/internal_api/public/base/model_type.h"
16 #include "sync/internal_api/public/read_node.h"
17 #include "sync/internal_api/public/read_transaction.h"
18 #include "sync/internal_api/public/test/test_user_share.h"
19 #include "sync/internal_api/public/user_share.h"
20 #include "sync/internal_api/public/write_node.h"
21 #include "sync/internal_api/public/write_transaction.h"
22 #include "testing/gtest/include/gtest/gtest.h"
23
24 namespace browser_sync {
25
26 namespace {
27
28 class SyncGenericChangeProcessorTest : public testing::Test {
29  public:
30   // It doesn't matter which type we use.  Just pick one.
31   static const syncer::ModelType kType = syncer::PREFERENCES;
32
33   SyncGenericChangeProcessorTest() :
34       loop_(base::MessageLoop::TYPE_UI),
35       sync_merge_result_(kType),
36       merge_result_ptr_factory_(&sync_merge_result_),
37       syncable_service_ptr_factory_(&fake_syncable_service_) {
38   }
39
40   virtual void SetUp() OVERRIDE {
41     test_user_share_.SetUp();
42     syncer::ModelTypeSet types = syncer::ProtocolTypes();
43     for (syncer::ModelTypeSet::Iterator iter = types.First(); iter.Good();
44          iter.Inc()) {
45       syncer::TestUserShare::CreateRoot(iter.Get(),
46                                         test_user_share_.user_share());
47     }
48     test_user_share_.encryption_handler()->Init();
49     change_processor_.reset(
50         new GenericChangeProcessor(
51             &data_type_error_handler_,
52             syncable_service_ptr_factory_.GetWeakPtr(),
53             merge_result_ptr_factory_.GetWeakPtr(),
54             test_user_share_.user_share()));
55   }
56
57   virtual void TearDown() OVERRIDE {
58     test_user_share_.TearDown();
59   }
60
61   void BuildChildNodes(int n) {
62     syncer::WriteTransaction trans(FROM_HERE, user_share());
63     syncer::ReadNode root(&trans);
64     ASSERT_EQ(syncer::BaseNode::INIT_OK,
65               root.InitByTagLookup(syncer::ModelTypeToRootTag(kType)));
66     for (int i = 0; i < n; ++i) {
67       syncer::WriteNode node(&trans);
68       node.InitUniqueByCreation(kType, root, base::StringPrintf("node%05d", i));
69     }
70   }
71
72   GenericChangeProcessor* change_processor() {
73     return change_processor_.get();
74   }
75
76   syncer::UserShare* user_share() {
77     return test_user_share_.user_share();
78   }
79
80  private:
81   base::MessageLoop loop_;
82
83   syncer::SyncMergeResult sync_merge_result_;
84   base::WeakPtrFactory<syncer::SyncMergeResult> merge_result_ptr_factory_;
85
86   syncer::FakeSyncableService fake_syncable_service_;
87   base::WeakPtrFactory<syncer::FakeSyncableService>
88       syncable_service_ptr_factory_;
89
90   DataTypeErrorHandlerMock data_type_error_handler_;
91   syncer::TestUserShare test_user_share_;
92
93   scoped_ptr<GenericChangeProcessor> change_processor_;
94 };
95
96 // Similar to above, but focused on the method that implements sync/api
97 // interfaces and is hence exposed to datatypes directly.
98 TEST_F(SyncGenericChangeProcessorTest, StressGetAllSyncData) {
99   const int kNumChildNodes = 1000;
100   const int kRepeatCount = 1;
101
102   ASSERT_NO_FATAL_FAILURE(BuildChildNodes(kNumChildNodes));
103
104   for (int i = 0; i < kRepeatCount; ++i) {
105     syncer::SyncDataList sync_data =
106         change_processor()->GetAllSyncData(kType);
107
108     // Start with a simple test.  We can add more in-depth testing later.
109     EXPECT_EQ(static_cast<size_t>(kNumChildNodes), sync_data.size());
110   }
111 }
112
113 TEST_F(SyncGenericChangeProcessorTest, SetGetPasswords) {
114   const int kNumPasswords = 10;
115   sync_pb::PasswordSpecificsData password_data;
116   password_data.set_username_value("user");
117
118   sync_pb::EntitySpecifics password_holder;
119
120   syncer::SyncChangeList change_list;
121   for (int i = 0; i < kNumPasswords; ++i) {
122     password_data.set_password_value(
123         base::StringPrintf("password%i", i));
124     password_holder.mutable_password()->mutable_client_only_encrypted_data()->
125         CopyFrom(password_data);
126     change_list.push_back(
127         syncer::SyncChange(FROM_HERE,
128                            syncer::SyncChange::ACTION_ADD,
129                            syncer::SyncData::CreateLocalData(
130                                base::StringPrintf("tag%i", i),
131                                base::StringPrintf("title%i", i),
132                                password_holder)));
133   }
134
135   ASSERT_FALSE(
136       change_processor()->ProcessSyncChanges(FROM_HERE, change_list).IsSet());
137
138   syncer::SyncDataList password_list(
139       change_processor()->GetAllSyncData(syncer::PASSWORDS));
140
141   ASSERT_EQ(password_list.size(), change_list.size());
142   for (int i = 0; i < kNumPasswords; ++i) {
143     // Verify the password is returned properly.
144     ASSERT_TRUE(password_list[i].GetSpecifics().has_password());
145     ASSERT_TRUE(password_list[i].GetSpecifics().password().
146                     has_client_only_encrypted_data());
147     ASSERT_FALSE(password_list[i].GetSpecifics().password().has_encrypted());
148     const sync_pb::PasswordSpecificsData& sync_password =
149         password_list[i].GetSpecifics().password().client_only_encrypted_data();
150     const sync_pb::PasswordSpecificsData& change_password =
151         change_list[i].sync_data().GetSpecifics().password().
152             client_only_encrypted_data();
153     ASSERT_EQ(sync_password.password_value(), change_password.password_value());
154     ASSERT_EQ(sync_password.username_value(), change_password.username_value());
155
156     // Verify the raw sync data was stored securely.
157     syncer::ReadTransaction read_transaction(FROM_HERE, user_share());
158     syncer::ReadNode node(&read_transaction);
159     ASSERT_EQ(node.InitByClientTagLookup(syncer::PASSWORDS,
160                                          base::StringPrintf("tag%i", i)),
161               syncer::BaseNode::INIT_OK);
162     ASSERT_EQ(node.GetTitle(), "encrypted");
163     const sync_pb::EntitySpecifics& raw_specifics = node.GetEntitySpecifics();
164     ASSERT_TRUE(raw_specifics.has_password());
165     ASSERT_TRUE(raw_specifics.password().has_encrypted());
166     ASSERT_FALSE(raw_specifics.password().has_client_only_encrypted_data());
167   }
168 }
169
170 TEST_F(SyncGenericChangeProcessorTest, UpdatePasswords) {
171   const int kNumPasswords = 10;
172   sync_pb::PasswordSpecificsData password_data;
173   password_data.set_username_value("user");
174
175   sync_pb::EntitySpecifics password_holder;
176
177   syncer::SyncChangeList change_list;
178   syncer::SyncChangeList change_list2;
179   for (int i = 0; i < kNumPasswords; ++i) {
180     password_data.set_password_value(
181         base::StringPrintf("password%i", i));
182     password_holder.mutable_password()->mutable_client_only_encrypted_data()->
183         CopyFrom(password_data);
184     change_list.push_back(
185         syncer::SyncChange(FROM_HERE,
186                            syncer::SyncChange::ACTION_ADD,
187                            syncer::SyncData::CreateLocalData(
188                                base::StringPrintf("tag%i", i),
189                                base::StringPrintf("title%i", i),
190                                password_holder)));
191     password_data.set_password_value(
192         base::StringPrintf("password_m%i", i));
193     password_holder.mutable_password()->mutable_client_only_encrypted_data()->
194         CopyFrom(password_data);
195     change_list2.push_back(
196         syncer::SyncChange(FROM_HERE,
197                            syncer::SyncChange::ACTION_UPDATE,
198                            syncer::SyncData::CreateLocalData(
199                                base::StringPrintf("tag%i", i),
200                                base::StringPrintf("title_m%i", i),
201                                password_holder)));
202   }
203
204   ASSERT_FALSE(
205       change_processor()->ProcessSyncChanges(FROM_HERE, change_list).IsSet());
206   ASSERT_FALSE(
207       change_processor()->ProcessSyncChanges(FROM_HERE, change_list2).IsSet());
208
209   syncer::SyncDataList password_list(
210       change_processor()->GetAllSyncData(syncer::PASSWORDS));
211
212   ASSERT_EQ(password_list.size(), change_list2.size());
213   for (int i = 0; i < kNumPasswords; ++i) {
214     // Verify the password is returned properly.
215     ASSERT_TRUE(password_list[i].GetSpecifics().has_password());
216     ASSERT_TRUE(password_list[i].GetSpecifics().password().
217                     has_client_only_encrypted_data());
218     ASSERT_FALSE(password_list[i].GetSpecifics().password().has_encrypted());
219     const sync_pb::PasswordSpecificsData& sync_password =
220         password_list[i].GetSpecifics().password().client_only_encrypted_data();
221     const sync_pb::PasswordSpecificsData& change_password =
222         change_list2[i].sync_data().GetSpecifics().password().
223             client_only_encrypted_data();
224     ASSERT_EQ(sync_password.password_value(), change_password.password_value());
225     ASSERT_EQ(sync_password.username_value(), change_password.username_value());
226
227     // Verify the raw sync data was stored securely.
228     syncer::ReadTransaction read_transaction(FROM_HERE, user_share());
229     syncer::ReadNode node(&read_transaction);
230     ASSERT_EQ(node.InitByClientTagLookup(syncer::PASSWORDS,
231                                          base::StringPrintf("tag%i", i)),
232               syncer::BaseNode::INIT_OK);
233     ASSERT_EQ(node.GetTitle(), "encrypted");
234     const sync_pb::EntitySpecifics& raw_specifics = node.GetEntitySpecifics();
235     ASSERT_TRUE(raw_specifics.has_password());
236     ASSERT_TRUE(raw_specifics.password().has_encrypted());
237     ASSERT_FALSE(raw_specifics.password().has_client_only_encrypted_data());
238   }
239 }
240
241 }  // namespace
242
243 }  // namespace browser_sync
244