Make |track_| in MediaStreamTrack const. and a couple of other cosmetic changes.
[chromium-blink-merge.git] / components / sync_driver / generic_change_processor_unittest.cc
blob56c953450600ce8f6166b7ad07f76faae2e08c77
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/run_loop.h"
11 #include "base/strings/stringprintf.h"
12 #include "components/sync_driver/data_type_error_handler_mock.h"
13 #include "components/sync_driver/sync_api_component_factory.h"
14 #include "sync/api/attachments/attachment_id.h"
15 #include "sync/api/attachments/attachment_store.h"
16 #include "sync/api/fake_syncable_service.h"
17 #include "sync/api/sync_change.h"
18 #include "sync/api/sync_merge_result.h"
19 #include "sync/internal_api/public/attachments/attachment_service_impl.h"
20 #include "sync/internal_api/public/attachments/fake_attachment_downloader.h"
21 #include "sync/internal_api/public/attachments/fake_attachment_uploader.h"
22 #include "sync/internal_api/public/base/model_type.h"
23 #include "sync/internal_api/public/read_node.h"
24 #include "sync/internal_api/public/read_transaction.h"
25 #include "sync/internal_api/public/sync_encryption_handler.h"
26 #include "sync/internal_api/public/test/test_user_share.h"
27 #include "sync/internal_api/public/user_share.h"
28 #include "sync/internal_api/public/write_node.h"
29 #include "sync/internal_api/public/write_transaction.h"
30 #include "testing/gmock/include/gmock/gmock-matchers.h"
31 #include "testing/gtest/include/gtest/gtest.h"
33 namespace sync_driver {
35 namespace {
37 // A mock that keeps track of attachments passed to UploadAttachments.
38 class MockAttachmentService : public syncer::AttachmentServiceImpl {
39 public:
40 MockAttachmentService(
41 const scoped_refptr<syncer::AttachmentStore>& attachment_store);
42 ~MockAttachmentService() override;
43 void UploadAttachments(
44 const syncer::AttachmentIdSet& attachment_ids) override;
45 std::vector<syncer::AttachmentIdSet>* attachment_id_sets();
47 private:
48 std::vector<syncer::AttachmentIdSet> attachment_id_sets_;
51 MockAttachmentService::MockAttachmentService(
52 const scoped_refptr<syncer::AttachmentStore>& attachment_store)
53 : AttachmentServiceImpl(attachment_store,
54 scoped_ptr<syncer::AttachmentUploader>(
55 new syncer::FakeAttachmentUploader),
56 scoped_ptr<syncer::AttachmentDownloader>(
57 new syncer::FakeAttachmentDownloader),
58 NULL,
59 base::TimeDelta(),
60 base::TimeDelta()) {
63 MockAttachmentService::~MockAttachmentService() {
66 void MockAttachmentService::UploadAttachments(
67 const syncer::AttachmentIdSet& attachment_ids) {
68 attachment_id_sets_.push_back(attachment_ids);
69 AttachmentServiceImpl::UploadAttachments(attachment_ids);
72 std::vector<syncer::AttachmentIdSet>*
73 MockAttachmentService::attachment_id_sets() {
74 return &attachment_id_sets_;
77 // MockSyncApiComponentFactory needed to initialize GenericChangeProcessor and
78 // pass MockAttachmentService to it.
79 class MockSyncApiComponentFactory : public SyncApiComponentFactory {
80 public:
81 MockSyncApiComponentFactory(
82 scoped_ptr<syncer::AttachmentService> attachment_service)
83 : attachment_service_(attachment_service.Pass()) {}
85 base::WeakPtr<syncer::SyncableService> GetSyncableServiceForType(
86 syncer::ModelType type) override {
87 // Shouldn't be called for this test.
88 NOTREACHED();
89 return base::WeakPtr<syncer::SyncableService>();
92 scoped_ptr<syncer::AttachmentService> CreateAttachmentService(
93 const scoped_refptr<syncer::AttachmentStore>& attachment_store,
94 const syncer::UserShare& user_share,
95 syncer::AttachmentService::Delegate* delegate) override {
96 EXPECT_TRUE(attachment_service_ != NULL);
97 return attachment_service_.Pass();
100 private:
101 scoped_ptr<syncer::AttachmentService> attachment_service_;
104 class SyncGenericChangeProcessorTest : public testing::Test {
105 public:
106 // Most test cases will use this type. For those that need a
107 // GenericChangeProcessor for a different type, use |InitializeForType|.
108 static const syncer::ModelType kType = syncer::PREFERENCES;
110 SyncGenericChangeProcessorTest()
111 : syncable_service_ptr_factory_(&fake_syncable_service_),
112 mock_attachment_service_(NULL) {}
114 virtual void SetUp() override {
115 // Use kType by default, but allow test cases to re-initialize with whatever
116 // type they choose. Therefore, it's important that all type dependent
117 // initialization occurs in InitializeForType.
118 InitializeForType(kType);
121 virtual void TearDown() override {
122 mock_attachment_service_ = NULL;
123 if (test_user_share_) {
124 test_user_share_->TearDown();
128 // Initialize GenericChangeProcessor and related classes for testing with
129 // model type |type|.
130 void InitializeForType(syncer::ModelType type) {
131 TearDown();
132 test_user_share_.reset(new syncer::TestUserShare);
133 test_user_share_->SetUp();
134 sync_merge_result_.reset(new syncer::SyncMergeResult(type));
135 merge_result_ptr_factory_.reset(
136 new base::WeakPtrFactory<syncer::SyncMergeResult>(
137 sync_merge_result_.get()));
139 syncer::ModelTypeSet types = syncer::ProtocolTypes();
140 for (syncer::ModelTypeSet::Iterator iter = types.First(); iter.Good();
141 iter.Inc()) {
142 syncer::TestUserShare::CreateRoot(iter.Get(),
143 test_user_share_->user_share());
145 test_user_share_->encryption_handler()->Init();
146 ConstructGenericChangeProcessor(type);
149 void ConstructGenericChangeProcessor(syncer::ModelType type) {
150 scoped_refptr<syncer::AttachmentStore> attachment_store =
151 syncer::AttachmentStore::CreateInMemoryStore();
152 scoped_ptr<MockAttachmentService> mock_attachment_service(
153 new MockAttachmentService(attachment_store));
154 // GenericChangeProcessor takes ownership of the AttachmentService, but we
155 // need to have a pointer to it so we can see that it was used properly.
156 // Take a pointer and trust that GenericChangeProcessor does not prematurely
157 // destroy it.
158 mock_attachment_service_ = mock_attachment_service.get();
159 sync_factory_.reset(
160 new MockSyncApiComponentFactory(mock_attachment_service.Pass()));
161 change_processor_.reset(
162 new GenericChangeProcessor(type,
163 &data_type_error_handler_,
164 syncable_service_ptr_factory_.GetWeakPtr(),
165 merge_result_ptr_factory_->GetWeakPtr(),
166 test_user_share_->user_share(),
167 sync_factory_.get(),
168 attachment_store));
171 void BuildChildNodes(syncer::ModelType type, int n) {
172 syncer::WriteTransaction trans(FROM_HERE, user_share());
173 syncer::ReadNode root(&trans);
174 ASSERT_EQ(syncer::BaseNode::INIT_OK, root.InitTypeRoot(type));
175 for (int i = 0; i < n; ++i) {
176 syncer::WriteNode node(&trans);
177 node.InitUniqueByCreation(type, root, base::StringPrintf("node%05d", i));
181 GenericChangeProcessor* change_processor() {
182 return change_processor_.get();
185 syncer::UserShare* user_share() {
186 return test_user_share_->user_share();
189 MockAttachmentService* mock_attachment_service() {
190 return mock_attachment_service_;
193 void RunLoop() {
194 base::RunLoop run_loop;
195 run_loop.RunUntilIdle();
198 private:
199 base::MessageLoopForUI loop_;
201 scoped_ptr<syncer::SyncMergeResult> sync_merge_result_;
202 scoped_ptr<base::WeakPtrFactory<syncer::SyncMergeResult> >
203 merge_result_ptr_factory_;
205 syncer::FakeSyncableService fake_syncable_service_;
206 base::WeakPtrFactory<syncer::FakeSyncableService>
207 syncable_service_ptr_factory_;
209 DataTypeErrorHandlerMock data_type_error_handler_;
210 scoped_ptr<syncer::TestUserShare> test_user_share_;
211 MockAttachmentService* mock_attachment_service_;
212 scoped_ptr<SyncApiComponentFactory> sync_factory_;
214 scoped_ptr<GenericChangeProcessor> change_processor_;
217 // Similar to above, but focused on the method that implements sync/api
218 // interfaces and is hence exposed to datatypes directly.
219 TEST_F(SyncGenericChangeProcessorTest, StressGetAllSyncData) {
220 const int kNumChildNodes = 1000;
221 const int kRepeatCount = 1;
223 ASSERT_NO_FATAL_FAILURE(BuildChildNodes(kType, kNumChildNodes));
225 for (int i = 0; i < kRepeatCount; ++i) {
226 syncer::SyncDataList sync_data =
227 change_processor()->GetAllSyncData(kType);
229 // Start with a simple test. We can add more in-depth testing later.
230 EXPECT_EQ(static_cast<size_t>(kNumChildNodes), sync_data.size());
234 TEST_F(SyncGenericChangeProcessorTest, SetGetPasswords) {
235 InitializeForType(syncer::PASSWORDS);
236 const int kNumPasswords = 10;
237 sync_pb::PasswordSpecificsData password_data;
238 password_data.set_username_value("user");
240 sync_pb::EntitySpecifics password_holder;
242 syncer::SyncChangeList change_list;
243 for (int i = 0; i < kNumPasswords; ++i) {
244 password_data.set_password_value(
245 base::StringPrintf("password%i", i));
246 password_holder.mutable_password()->mutable_client_only_encrypted_data()->
247 CopyFrom(password_data);
248 change_list.push_back(
249 syncer::SyncChange(FROM_HERE,
250 syncer::SyncChange::ACTION_ADD,
251 syncer::SyncData::CreateLocalData(
252 base::StringPrintf("tag%i", i),
253 base::StringPrintf("title%i", i),
254 password_holder)));
257 ASSERT_FALSE(
258 change_processor()->ProcessSyncChanges(FROM_HERE, change_list).IsSet());
260 syncer::SyncDataList password_list(
261 change_processor()->GetAllSyncData(syncer::PASSWORDS));
263 ASSERT_EQ(password_list.size(), change_list.size());
264 for (int i = 0; i < kNumPasswords; ++i) {
265 // Verify the password is returned properly.
266 ASSERT_TRUE(password_list[i].GetSpecifics().has_password());
267 ASSERT_TRUE(password_list[i].GetSpecifics().password().
268 has_client_only_encrypted_data());
269 ASSERT_FALSE(password_list[i].GetSpecifics().password().has_encrypted());
270 const sync_pb::PasswordSpecificsData& sync_password =
271 password_list[i].GetSpecifics().password().client_only_encrypted_data();
272 const sync_pb::PasswordSpecificsData& change_password =
273 change_list[i].sync_data().GetSpecifics().password().
274 client_only_encrypted_data();
275 ASSERT_EQ(sync_password.password_value(), change_password.password_value());
276 ASSERT_EQ(sync_password.username_value(), change_password.username_value());
278 // Verify the raw sync data was stored securely.
279 syncer::ReadTransaction read_transaction(FROM_HERE, user_share());
280 syncer::ReadNode node(&read_transaction);
281 ASSERT_EQ(node.InitByClientTagLookup(syncer::PASSWORDS,
282 base::StringPrintf("tag%i", i)),
283 syncer::BaseNode::INIT_OK);
284 ASSERT_EQ(node.GetTitle(), "encrypted");
285 const sync_pb::EntitySpecifics& raw_specifics = node.GetEntitySpecifics();
286 ASSERT_TRUE(raw_specifics.has_password());
287 ASSERT_TRUE(raw_specifics.password().has_encrypted());
288 ASSERT_FALSE(raw_specifics.password().has_client_only_encrypted_data());
292 TEST_F(SyncGenericChangeProcessorTest, UpdatePasswords) {
293 InitializeForType(syncer::PASSWORDS);
294 const int kNumPasswords = 10;
295 sync_pb::PasswordSpecificsData password_data;
296 password_data.set_username_value("user");
298 sync_pb::EntitySpecifics password_holder;
300 syncer::SyncChangeList change_list;
301 syncer::SyncChangeList change_list2;
302 for (int i = 0; i < kNumPasswords; ++i) {
303 password_data.set_password_value(
304 base::StringPrintf("password%i", i));
305 password_holder.mutable_password()->mutable_client_only_encrypted_data()->
306 CopyFrom(password_data);
307 change_list.push_back(
308 syncer::SyncChange(FROM_HERE,
309 syncer::SyncChange::ACTION_ADD,
310 syncer::SyncData::CreateLocalData(
311 base::StringPrintf("tag%i", i),
312 base::StringPrintf("title%i", i),
313 password_holder)));
314 password_data.set_password_value(
315 base::StringPrintf("password_m%i", i));
316 password_holder.mutable_password()->mutable_client_only_encrypted_data()->
317 CopyFrom(password_data);
318 change_list2.push_back(
319 syncer::SyncChange(FROM_HERE,
320 syncer::SyncChange::ACTION_UPDATE,
321 syncer::SyncData::CreateLocalData(
322 base::StringPrintf("tag%i", i),
323 base::StringPrintf("title_m%i", i),
324 password_holder)));
327 ASSERT_FALSE(
328 change_processor()->ProcessSyncChanges(FROM_HERE, change_list).IsSet());
329 ASSERT_FALSE(
330 change_processor()->ProcessSyncChanges(FROM_HERE, change_list2).IsSet());
332 syncer::SyncDataList password_list(
333 change_processor()->GetAllSyncData(syncer::PASSWORDS));
335 ASSERT_EQ(password_list.size(), change_list2.size());
336 for (int i = 0; i < kNumPasswords; ++i) {
337 // Verify the password is returned properly.
338 ASSERT_TRUE(password_list[i].GetSpecifics().has_password());
339 ASSERT_TRUE(password_list[i].GetSpecifics().password().
340 has_client_only_encrypted_data());
341 ASSERT_FALSE(password_list[i].GetSpecifics().password().has_encrypted());
342 const sync_pb::PasswordSpecificsData& sync_password =
343 password_list[i].GetSpecifics().password().client_only_encrypted_data();
344 const sync_pb::PasswordSpecificsData& change_password =
345 change_list2[i].sync_data().GetSpecifics().password().
346 client_only_encrypted_data();
347 ASSERT_EQ(sync_password.password_value(), change_password.password_value());
348 ASSERT_EQ(sync_password.username_value(), change_password.username_value());
350 // Verify the raw sync data was stored securely.
351 syncer::ReadTransaction read_transaction(FROM_HERE, user_share());
352 syncer::ReadNode node(&read_transaction);
353 ASSERT_EQ(node.InitByClientTagLookup(syncer::PASSWORDS,
354 base::StringPrintf("tag%i", i)),
355 syncer::BaseNode::INIT_OK);
356 ASSERT_EQ(node.GetTitle(), "encrypted");
357 const sync_pb::EntitySpecifics& raw_specifics = node.GetEntitySpecifics();
358 ASSERT_TRUE(raw_specifics.has_password());
359 ASSERT_TRUE(raw_specifics.password().has_encrypted());
360 ASSERT_FALSE(raw_specifics.password().has_client_only_encrypted_data());
364 // Verify that attachments on newly added or updated SyncData are passed to the
365 // AttachmentService.
366 TEST_F(SyncGenericChangeProcessorTest,
367 ProcessSyncChanges_AddUpdateWithAttachment) {
368 std::string tag = "client_tag";
369 std::string title = "client_title";
370 sync_pb::EntitySpecifics specifics;
371 sync_pb::PreferenceSpecifics* pref_specifics = specifics.mutable_preference();
372 pref_specifics->set_name("test");
374 syncer::AttachmentIdList attachment_ids;
375 attachment_ids.push_back(syncer::AttachmentId::Create());
376 attachment_ids.push_back(syncer::AttachmentId::Create());
378 // Add a SyncData with two attachments.
379 syncer::SyncChangeList change_list;
380 change_list.push_back(
381 syncer::SyncChange(FROM_HERE,
382 syncer::SyncChange::ACTION_ADD,
383 syncer::SyncData::CreateLocalDataWithAttachments(
384 tag, title, specifics, attachment_ids)));
385 ASSERT_FALSE(
386 change_processor()->ProcessSyncChanges(FROM_HERE, change_list).IsSet());
387 RunLoop();
389 // Check that the AttachmentService received the new attachments.
390 ASSERT_EQ(mock_attachment_service()->attachment_id_sets()->size(), 1U);
391 const syncer::AttachmentIdSet& attachments_added =
392 mock_attachment_service()->attachment_id_sets()->front();
393 ASSERT_THAT(
394 attachments_added,
395 testing::UnorderedElementsAre(attachment_ids[0], attachment_ids[1]));
397 // Update the SyncData, replacing its two attachments with one new attachment.
398 syncer::AttachmentIdList new_attachment_ids;
399 new_attachment_ids.push_back(syncer::AttachmentId::Create());
400 mock_attachment_service()->attachment_id_sets()->clear();
401 change_list.clear();
402 change_list.push_back(
403 syncer::SyncChange(FROM_HERE,
404 syncer::SyncChange::ACTION_UPDATE,
405 syncer::SyncData::CreateLocalDataWithAttachments(
406 tag, title, specifics, new_attachment_ids)));
407 ASSERT_FALSE(
408 change_processor()->ProcessSyncChanges(FROM_HERE, change_list).IsSet());
409 RunLoop();
411 // Check that the AttachmentService received it.
412 ASSERT_EQ(mock_attachment_service()->attachment_id_sets()->size(), 1U);
413 const syncer::AttachmentIdSet& new_attachments_added =
414 mock_attachment_service()->attachment_id_sets()->front();
415 ASSERT_THAT(new_attachments_added,
416 testing::UnorderedElementsAre(new_attachment_ids[0]));
419 // Verify that after attachment is uploaded GenericChangeProcessor updates
420 // corresponding entries
421 TEST_F(SyncGenericChangeProcessorTest, AttachmentUploaded) {
422 std::string tag = "client_tag";
423 std::string title = "client_title";
424 sync_pb::EntitySpecifics specifics;
425 sync_pb::PreferenceSpecifics* pref_specifics = specifics.mutable_preference();
426 pref_specifics->set_name("test");
428 syncer::AttachmentIdList attachment_ids;
429 attachment_ids.push_back(syncer::AttachmentId::Create());
431 // Add a SyncData with two attachments.
432 syncer::SyncChangeList change_list;
433 change_list.push_back(
434 syncer::SyncChange(FROM_HERE,
435 syncer::SyncChange::ACTION_ADD,
436 syncer::SyncData::CreateLocalDataWithAttachments(
437 tag, title, specifics, attachment_ids)));
438 ASSERT_FALSE(
439 change_processor()->ProcessSyncChanges(FROM_HERE, change_list).IsSet());
441 sync_pb::AttachmentIdProto attachment_id_proto = attachment_ids[0].GetProto();
442 syncer::AttachmentId attachment_id =
443 syncer::AttachmentId::CreateFromProto(attachment_id_proto);
445 change_processor()->OnAttachmentUploaded(attachment_id);
446 syncer::ReadTransaction read_transaction(FROM_HERE, user_share());
447 syncer::ReadNode node(&read_transaction);
448 ASSERT_EQ(node.InitByClientTagLookup(kType, tag), syncer::BaseNode::INIT_OK);
449 attachment_ids = node.GetAttachmentIds();
450 EXPECT_EQ(1U, attachment_ids.size());
453 // Verify that upon construction, all attachments not yet on the server are
454 // scheduled for upload.
455 TEST_F(SyncGenericChangeProcessorTest, UploadAllAttachmentsNotOnServer) {
456 // Create two attachment ids. id2 will be marked as "on server".
457 syncer::AttachmentId id1 = syncer::AttachmentId::Create();
458 syncer::AttachmentId id2 = syncer::AttachmentId::Create();
460 // Write an entry containing these two attachment ids.
461 syncer::WriteTransaction trans(FROM_HERE, user_share());
462 syncer::ReadNode root(&trans);
463 ASSERT_EQ(syncer::BaseNode::INIT_OK, root.InitTypeRoot(kType));
464 syncer::WriteNode node(&trans);
465 node.InitUniqueByCreation(kType, root, "some node");
466 sync_pb::AttachmentMetadata metadata;
467 sync_pb::AttachmentMetadataRecord* record1 = metadata.add_record();
468 *record1->mutable_id() = id1.GetProto();
469 sync_pb::AttachmentMetadataRecord* record2 = metadata.add_record();
470 *record2->mutable_id() = id2.GetProto();
471 record2->set_is_on_server(true);
472 node.SetAttachmentMetadata(metadata);
475 // Construct the GenericChangeProcessor and see that it asks the
476 // AttachmentService to upload id1 only.
477 ConstructGenericChangeProcessor(kType);
478 ASSERT_EQ(1U, mock_attachment_service()->attachment_id_sets()->size());
479 ASSERT_THAT(mock_attachment_service()->attachment_id_sets()->front(),
480 testing::UnorderedElementsAre(id1));
483 } // namespace
485 } // namespace sync_driver