Make sure webrtc::VideoSource is released when WebRtcVideoTrackAdapter is destroyed.
[chromium-blink-merge.git] / components / sync_driver / generic_change_processor_unittest.cc
blobc5259189a87219f1306b31100d3a1aac8ebc00ae
1 // Copyright 2014 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 "components/sync_driver/generic_change_processor.h"
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 "components/sync_driver/data_type_error_handler_mock.h"
12 #include "components/sync_driver/sync_api_component_factory.h"
13 #include "sync/api/attachments/attachment_service_impl.h"
14 #include "sync/api/fake_syncable_service.h"
15 #include "sync/api/sync_change.h"
16 #include "sync/api/sync_merge_result.h"
17 #include "sync/internal_api/public/attachments/fake_attachment_store.h"
18 #include "sync/internal_api/public/attachments/fake_attachment_uploader.h"
19 #include "sync/internal_api/public/base/model_type.h"
20 #include "sync/internal_api/public/read_node.h"
21 #include "sync/internal_api/public/read_transaction.h"
22 #include "sync/internal_api/public/sync_encryption_handler.h"
23 #include "sync/internal_api/public/test/test_user_share.h"
24 #include "sync/internal_api/public/user_share.h"
25 #include "sync/internal_api/public/write_node.h"
26 #include "sync/internal_api/public/write_transaction.h"
27 #include "testing/gtest/include/gtest/gtest.h"
29 namespace browser_sync {
31 namespace {
33 const char kTestData[] = "some data";
35 // A mock that keeps track of attachments passed to StoreAttachments.
36 class MockAttachmentService : public syncer::AttachmentServiceImpl {
37 public:
38 MockAttachmentService();
39 virtual ~MockAttachmentService();
40 virtual void StoreAttachments(const syncer::AttachmentList& attachments,
41 const StoreCallback& callback) OVERRIDE;
42 std::vector<syncer::AttachmentList>* attachment_lists();
44 private:
45 std::vector<syncer::AttachmentList> attachment_lists_;
48 MockAttachmentService::MockAttachmentService()
49 : AttachmentServiceImpl(
50 scoped_ptr<syncer::AttachmentStore>(new syncer::FakeAttachmentStore(
51 base::MessageLoopProxy::current())),
52 scoped_ptr<syncer::AttachmentUploader>(
53 new syncer::FakeAttachmentUploader),
54 NULL) {
57 MockAttachmentService::~MockAttachmentService() {
60 void MockAttachmentService::StoreAttachments(
61 const syncer::AttachmentList& attachments,
62 const StoreCallback& callback) {
63 attachment_lists_.push_back(attachments);
64 AttachmentServiceImpl::StoreAttachments(attachments, callback);
67 std::vector<syncer::AttachmentList>* MockAttachmentService::attachment_lists() {
68 return &attachment_lists_;
71 // MockSyncApiComponentFactory needed to initialize GenericChangeProcessor and
72 // pass MockAttachmentService to it.
73 class MockSyncApiComponentFactory : public SyncApiComponentFactory {
74 public:
75 MockSyncApiComponentFactory(
76 scoped_ptr<syncer::AttachmentService> attachment_service)
77 : attachment_service_(attachment_service.Pass()) {}
79 virtual base::WeakPtr<syncer::SyncableService> GetSyncableServiceForType(
80 syncer::ModelType type) OVERRIDE {
81 // Shouldn't be called for this test.
82 NOTREACHED();
83 return base::WeakPtr<syncer::SyncableService>();
86 virtual scoped_ptr<syncer::AttachmentService> CreateAttachmentService(
87 syncer::AttachmentService::Delegate* delegate) OVERRIDE {
88 EXPECT_TRUE(attachment_service_ != NULL);
89 return attachment_service_.Pass();
92 private:
93 scoped_ptr<syncer::AttachmentService> attachment_service_;
96 class SyncGenericChangeProcessorTest : public testing::Test {
97 public:
98 // It doesn't matter which type we use. Just pick one.
99 static const syncer::ModelType kType = syncer::PREFERENCES;
101 SyncGenericChangeProcessorTest()
102 : sync_merge_result_(kType),
103 merge_result_ptr_factory_(&sync_merge_result_),
104 syncable_service_ptr_factory_(&fake_syncable_service_),
105 mock_attachment_service_(NULL) {}
107 virtual void SetUp() OVERRIDE {
108 test_user_share_.SetUp();
109 syncer::ModelTypeSet types = syncer::ProtocolTypes();
110 for (syncer::ModelTypeSet::Iterator iter = types.First(); iter.Good();
111 iter.Inc()) {
112 syncer::TestUserShare::CreateRoot(iter.Get(),
113 test_user_share_.user_share());
115 test_user_share_.encryption_handler()->Init();
116 scoped_ptr<MockAttachmentService> mock_attachment_service(
117 new MockAttachmentService);
118 // GenericChangeProcessor takes ownership of the AttachmentService, but we
119 // need to have a pointer to it so we can see that it was used properly.
120 // Take a pointer and trust that GenericChangeProcessor does not prematurely
121 // destroy it.
122 mock_attachment_service_ = mock_attachment_service.get();
123 sync_factory_.reset(new MockSyncApiComponentFactory(
124 mock_attachment_service.PassAs<syncer::AttachmentService>()));
125 change_processor_.reset(
126 new GenericChangeProcessor(&data_type_error_handler_,
127 syncable_service_ptr_factory_.GetWeakPtr(),
128 merge_result_ptr_factory_.GetWeakPtr(),
129 test_user_share_.user_share(),
130 sync_factory_.get()));
133 virtual void TearDown() OVERRIDE {
134 mock_attachment_service_ = NULL;
135 test_user_share_.TearDown();
138 void BuildChildNodes(int n) {
139 syncer::WriteTransaction trans(FROM_HERE, user_share());
140 syncer::ReadNode root(&trans);
141 ASSERT_EQ(syncer::BaseNode::INIT_OK,
142 root.InitByTagLookup(syncer::ModelTypeToRootTag(kType)));
143 for (int i = 0; i < n; ++i) {
144 syncer::WriteNode node(&trans);
145 node.InitUniqueByCreation(kType, root, base::StringPrintf("node%05d", i));
149 GenericChangeProcessor* change_processor() {
150 return change_processor_.get();
153 syncer::UserShare* user_share() {
154 return test_user_share_.user_share();
157 MockAttachmentService* mock_attachment_service() {
158 return mock_attachment_service_;
161 private:
162 base::MessageLoopForUI loop_;
164 syncer::SyncMergeResult sync_merge_result_;
165 base::WeakPtrFactory<syncer::SyncMergeResult> merge_result_ptr_factory_;
167 syncer::FakeSyncableService fake_syncable_service_;
168 base::WeakPtrFactory<syncer::FakeSyncableService>
169 syncable_service_ptr_factory_;
171 DataTypeErrorHandlerMock data_type_error_handler_;
172 syncer::TestUserShare test_user_share_;
173 MockAttachmentService* mock_attachment_service_;
174 scoped_ptr<SyncApiComponentFactory> sync_factory_;
176 scoped_ptr<GenericChangeProcessor> change_processor_;
179 // Similar to above, but focused on the method that implements sync/api
180 // interfaces and is hence exposed to datatypes directly.
181 TEST_F(SyncGenericChangeProcessorTest, StressGetAllSyncData) {
182 const int kNumChildNodes = 1000;
183 const int kRepeatCount = 1;
185 ASSERT_NO_FATAL_FAILURE(BuildChildNodes(kNumChildNodes));
187 for (int i = 0; i < kRepeatCount; ++i) {
188 syncer::SyncDataList sync_data =
189 change_processor()->GetAllSyncData(kType);
191 // Start with a simple test. We can add more in-depth testing later.
192 EXPECT_EQ(static_cast<size_t>(kNumChildNodes), sync_data.size());
196 TEST_F(SyncGenericChangeProcessorTest, SetGetPasswords) {
197 const int kNumPasswords = 10;
198 sync_pb::PasswordSpecificsData password_data;
199 password_data.set_username_value("user");
201 sync_pb::EntitySpecifics password_holder;
203 syncer::SyncChangeList change_list;
204 for (int i = 0; i < kNumPasswords; ++i) {
205 password_data.set_password_value(
206 base::StringPrintf("password%i", i));
207 password_holder.mutable_password()->mutable_client_only_encrypted_data()->
208 CopyFrom(password_data);
209 change_list.push_back(
210 syncer::SyncChange(FROM_HERE,
211 syncer::SyncChange::ACTION_ADD,
212 syncer::SyncData::CreateLocalData(
213 base::StringPrintf("tag%i", i),
214 base::StringPrintf("title%i", i),
215 password_holder)));
218 ASSERT_FALSE(
219 change_processor()->ProcessSyncChanges(FROM_HERE, change_list).IsSet());
221 syncer::SyncDataList password_list(
222 change_processor()->GetAllSyncData(syncer::PASSWORDS));
224 ASSERT_EQ(password_list.size(), change_list.size());
225 for (int i = 0; i < kNumPasswords; ++i) {
226 // Verify the password is returned properly.
227 ASSERT_TRUE(password_list[i].GetSpecifics().has_password());
228 ASSERT_TRUE(password_list[i].GetSpecifics().password().
229 has_client_only_encrypted_data());
230 ASSERT_FALSE(password_list[i].GetSpecifics().password().has_encrypted());
231 const sync_pb::PasswordSpecificsData& sync_password =
232 password_list[i].GetSpecifics().password().client_only_encrypted_data();
233 const sync_pb::PasswordSpecificsData& change_password =
234 change_list[i].sync_data().GetSpecifics().password().
235 client_only_encrypted_data();
236 ASSERT_EQ(sync_password.password_value(), change_password.password_value());
237 ASSERT_EQ(sync_password.username_value(), change_password.username_value());
239 // Verify the raw sync data was stored securely.
240 syncer::ReadTransaction read_transaction(FROM_HERE, user_share());
241 syncer::ReadNode node(&read_transaction);
242 ASSERT_EQ(node.InitByClientTagLookup(syncer::PASSWORDS,
243 base::StringPrintf("tag%i", i)),
244 syncer::BaseNode::INIT_OK);
245 ASSERT_EQ(node.GetTitle(), "encrypted");
246 const sync_pb::EntitySpecifics& raw_specifics = node.GetEntitySpecifics();
247 ASSERT_TRUE(raw_specifics.has_password());
248 ASSERT_TRUE(raw_specifics.password().has_encrypted());
249 ASSERT_FALSE(raw_specifics.password().has_client_only_encrypted_data());
253 TEST_F(SyncGenericChangeProcessorTest, UpdatePasswords) {
254 const int kNumPasswords = 10;
255 sync_pb::PasswordSpecificsData password_data;
256 password_data.set_username_value("user");
258 sync_pb::EntitySpecifics password_holder;
260 syncer::SyncChangeList change_list;
261 syncer::SyncChangeList change_list2;
262 for (int i = 0; i < kNumPasswords; ++i) {
263 password_data.set_password_value(
264 base::StringPrintf("password%i", i));
265 password_holder.mutable_password()->mutable_client_only_encrypted_data()->
266 CopyFrom(password_data);
267 change_list.push_back(
268 syncer::SyncChange(FROM_HERE,
269 syncer::SyncChange::ACTION_ADD,
270 syncer::SyncData::CreateLocalData(
271 base::StringPrintf("tag%i", i),
272 base::StringPrintf("title%i", i),
273 password_holder)));
274 password_data.set_password_value(
275 base::StringPrintf("password_m%i", i));
276 password_holder.mutable_password()->mutable_client_only_encrypted_data()->
277 CopyFrom(password_data);
278 change_list2.push_back(
279 syncer::SyncChange(FROM_HERE,
280 syncer::SyncChange::ACTION_UPDATE,
281 syncer::SyncData::CreateLocalData(
282 base::StringPrintf("tag%i", i),
283 base::StringPrintf("title_m%i", i),
284 password_holder)));
287 ASSERT_FALSE(
288 change_processor()->ProcessSyncChanges(FROM_HERE, change_list).IsSet());
289 ASSERT_FALSE(
290 change_processor()->ProcessSyncChanges(FROM_HERE, change_list2).IsSet());
292 syncer::SyncDataList password_list(
293 change_processor()->GetAllSyncData(syncer::PASSWORDS));
295 ASSERT_EQ(password_list.size(), change_list2.size());
296 for (int i = 0; i < kNumPasswords; ++i) {
297 // Verify the password is returned properly.
298 ASSERT_TRUE(password_list[i].GetSpecifics().has_password());
299 ASSERT_TRUE(password_list[i].GetSpecifics().password().
300 has_client_only_encrypted_data());
301 ASSERT_FALSE(password_list[i].GetSpecifics().password().has_encrypted());
302 const sync_pb::PasswordSpecificsData& sync_password =
303 password_list[i].GetSpecifics().password().client_only_encrypted_data();
304 const sync_pb::PasswordSpecificsData& change_password =
305 change_list2[i].sync_data().GetSpecifics().password().
306 client_only_encrypted_data();
307 ASSERT_EQ(sync_password.password_value(), change_password.password_value());
308 ASSERT_EQ(sync_password.username_value(), change_password.username_value());
310 // Verify the raw sync data was stored securely.
311 syncer::ReadTransaction read_transaction(FROM_HERE, user_share());
312 syncer::ReadNode node(&read_transaction);
313 ASSERT_EQ(node.InitByClientTagLookup(syncer::PASSWORDS,
314 base::StringPrintf("tag%i", i)),
315 syncer::BaseNode::INIT_OK);
316 ASSERT_EQ(node.GetTitle(), "encrypted");
317 const sync_pb::EntitySpecifics& raw_specifics = node.GetEntitySpecifics();
318 ASSERT_TRUE(raw_specifics.has_password());
319 ASSERT_TRUE(raw_specifics.password().has_encrypted());
320 ASSERT_FALSE(raw_specifics.password().has_client_only_encrypted_data());
324 // Verify that attachments on newly added or updated SyncData are passed to the
325 // AttachmentService.
326 TEST_F(SyncGenericChangeProcessorTest,
327 ProcessSyncChanges_AddUpdateWithAttachment) {
328 std::string tag = "client_tag";
329 std::string title = "client_title";
330 sync_pb::EntitySpecifics specifics;
331 sync_pb::PreferenceSpecifics* pref_specifics = specifics.mutable_preference();
332 pref_specifics->set_name("test");
333 syncer::AttachmentList attachments;
334 scoped_refptr<base::RefCountedString> attachment_data =
335 new base::RefCountedString;
336 attachment_data->data() = kTestData;
337 attachments.push_back(syncer::Attachment::Create(attachment_data));
338 attachments.push_back(syncer::Attachment::Create(attachment_data));
340 // Add a SyncData with two attachments.
341 syncer::SyncChangeList change_list;
342 change_list.push_back(
343 syncer::SyncChange(FROM_HERE,
344 syncer::SyncChange::ACTION_ADD,
345 syncer::SyncData::CreateLocalDataWithAttachments(
346 tag, title, specifics, attachments)));
347 ASSERT_FALSE(
348 change_processor()->ProcessSyncChanges(FROM_HERE, change_list).IsSet());
350 // Check that the AttachmentService received the new attachments.
351 ASSERT_EQ(mock_attachment_service()->attachment_lists()->size(), 1U);
352 const syncer::AttachmentList& attachments_added =
353 mock_attachment_service()->attachment_lists()->front();
354 ASSERT_EQ(attachments_added.size(), 2U);
355 ASSERT_EQ(attachments_added[0].GetId(), attachments[0].GetId());
356 ASSERT_EQ(attachments_added[1].GetId(), attachments[1].GetId());
358 // Update the SyncData, replacing its two attachments with one new attachment.
359 syncer::AttachmentList new_attachments;
360 new_attachments.push_back(syncer::Attachment::Create(attachment_data));
361 mock_attachment_service()->attachment_lists()->clear();
362 change_list.clear();
363 change_list.push_back(
364 syncer::SyncChange(FROM_HERE,
365 syncer::SyncChange::ACTION_UPDATE,
366 syncer::SyncData::CreateLocalDataWithAttachments(
367 tag, title, specifics, new_attachments)));
368 ASSERT_FALSE(
369 change_processor()->ProcessSyncChanges(FROM_HERE, change_list).IsSet());
371 // Check that the AttachmentService received it.
372 ASSERT_EQ(mock_attachment_service()->attachment_lists()->size(), 1U);
373 const syncer::AttachmentList& new_attachments_added =
374 mock_attachment_service()->attachment_lists()->front();
375 ASSERT_EQ(new_attachments_added.size(), 1U);
376 ASSERT_EQ(new_attachments_added[0].GetId(), new_attachments[0].GetId());
379 // Verify that after attachment is uploaded GenericChangeProcessor updates
380 // corresponding entries
381 TEST_F(SyncGenericChangeProcessorTest, AttachmentUploaded) {
382 std::string tag = "client_tag";
383 std::string title = "client_title";
384 sync_pb::EntitySpecifics specifics;
385 sync_pb::PreferenceSpecifics* pref_specifics = specifics.mutable_preference();
386 pref_specifics->set_name("test");
387 syncer::AttachmentList attachments;
388 scoped_refptr<base::RefCountedString> attachment_data =
389 new base::RefCountedString;
390 attachment_data->data() = kTestData;
391 attachments.push_back(syncer::Attachment::Create(attachment_data));
393 // Add a SyncData with two attachments.
394 syncer::SyncChangeList change_list;
395 change_list.push_back(
396 syncer::SyncChange(FROM_HERE,
397 syncer::SyncChange::ACTION_ADD,
398 syncer::SyncData::CreateLocalDataWithAttachments(
399 tag, title, specifics, attachments)));
400 ASSERT_FALSE(
401 change_processor()->ProcessSyncChanges(FROM_HERE, change_list).IsSet());
403 sync_pb::AttachmentIdProto attachment_id_proto =
404 attachments[0].GetId().GetProto();
405 syncer::AttachmentId attachment_id =
406 syncer::AttachmentId::CreateFromProto(attachment_id_proto);
408 change_processor()->OnAttachmentUploaded(attachment_id);
409 syncer::ReadTransaction read_transaction(FROM_HERE, user_share());
410 syncer::ReadNode node(&read_transaction);
411 ASSERT_EQ(node.InitByClientTagLookup(syncer::PREFERENCES, tag),
412 syncer::BaseNode::INIT_OK);
413 syncer::AttachmentIdList attachment_ids = node.GetAttachmentIds();
414 EXPECT_EQ(1U, attachment_ids.size());
417 } // namespace
419 } // namespace browser_sync