OLD | NEW |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "components/sync_driver/generic_change_processor.h" | 5 #include "components/sync_driver/generic_change_processor.h" |
6 | 6 |
7 #include "base/memory/scoped_ptr.h" | 7 #include "base/memory/scoped_ptr.h" |
8 #include "base/memory/weak_ptr.h" | 8 #include "base/memory/weak_ptr.h" |
9 #include "base/message_loop/message_loop.h" | 9 #include "base/message_loop/message_loop.h" |
10 #include "base/strings/stringprintf.h" | 10 #include "base/strings/stringprintf.h" |
11 #include "components/sync_driver/data_type_error_handler_mock.h" | 11 #include "components/sync_driver/data_type_error_handler_mock.h" |
12 #include "sync/api/attachments/fake_attachment_service.h" | 12 #include "sync/api/attachments/fake_attachment_service.h" |
| 13 #include "sync/api/attachments/fake_attachment_store.h" |
13 #include "sync/api/fake_syncable_service.h" | 14 #include "sync/api/fake_syncable_service.h" |
14 #include "sync/api/sync_change.h" | 15 #include "sync/api/sync_change.h" |
15 #include "sync/api/sync_merge_result.h" | 16 #include "sync/api/sync_merge_result.h" |
16 #include "sync/internal_api/public/base/model_type.h" | 17 #include "sync/internal_api/public/base/model_type.h" |
17 #include "sync/internal_api/public/read_node.h" | 18 #include "sync/internal_api/public/read_node.h" |
18 #include "sync/internal_api/public/read_transaction.h" | 19 #include "sync/internal_api/public/read_transaction.h" |
19 #include "sync/internal_api/public/sync_encryption_handler.h" | 20 #include "sync/internal_api/public/sync_encryption_handler.h" |
20 #include "sync/internal_api/public/test/test_user_share.h" | 21 #include "sync/internal_api/public/test/test_user_share.h" |
21 #include "sync/internal_api/public/user_share.h" | 22 #include "sync/internal_api/public/user_share.h" |
22 #include "sync/internal_api/public/write_node.h" | 23 #include "sync/internal_api/public/write_node.h" |
23 #include "sync/internal_api/public/write_transaction.h" | 24 #include "sync/internal_api/public/write_transaction.h" |
24 #include "testing/gtest/include/gtest/gtest.h" | 25 #include "testing/gtest/include/gtest/gtest.h" |
25 | 26 |
26 namespace browser_sync { | 27 namespace browser_sync { |
27 | 28 |
28 namespace { | 29 namespace { |
29 | 30 |
| 31 const char kTestData[] = "some data"; |
| 32 |
| 33 // A mock that keeps track of attachments passed to StoreAttachments. |
| 34 class MockAttachmentService : public syncer::FakeAttachmentService { |
| 35 public: |
| 36 MockAttachmentService(); |
| 37 virtual ~MockAttachmentService(); |
| 38 virtual void StoreAttachments(const syncer::AttachmentList& attachments, |
| 39 const StoreCallback& callback) OVERRIDE; |
| 40 std::vector<syncer::AttachmentList>* attachment_lists(); |
| 41 |
| 42 private: |
| 43 std::vector<syncer::AttachmentList> attachment_lists_; |
| 44 }; |
| 45 |
| 46 MockAttachmentService::MockAttachmentService() |
| 47 : FakeAttachmentService(scoped_ptr<syncer::AttachmentStore>( |
| 48 new syncer::FakeAttachmentStore(base::MessageLoopProxy::current()))) { |
| 49 } |
| 50 |
| 51 MockAttachmentService::~MockAttachmentService() { |
| 52 } |
| 53 |
| 54 void MockAttachmentService::StoreAttachments( |
| 55 const syncer::AttachmentList& attachments, |
| 56 const StoreCallback& callback) { |
| 57 attachment_lists_.push_back(attachments); |
| 58 FakeAttachmentService::StoreAttachments(attachments, callback); |
| 59 } |
| 60 |
| 61 std::vector<syncer::AttachmentList>* MockAttachmentService::attachment_lists() { |
| 62 return &attachment_lists_; |
| 63 } |
| 64 |
30 class SyncGenericChangeProcessorTest : public testing::Test { | 65 class SyncGenericChangeProcessorTest : public testing::Test { |
31 public: | 66 public: |
32 // It doesn't matter which type we use. Just pick one. | 67 // It doesn't matter which type we use. Just pick one. |
33 static const syncer::ModelType kType = syncer::PREFERENCES; | 68 static const syncer::ModelType kType = syncer::PREFERENCES; |
34 | 69 |
35 SyncGenericChangeProcessorTest() : | 70 SyncGenericChangeProcessorTest() |
36 sync_merge_result_(kType), | 71 : sync_merge_result_(kType), |
37 merge_result_ptr_factory_(&sync_merge_result_), | 72 merge_result_ptr_factory_(&sync_merge_result_), |
38 syncable_service_ptr_factory_(&fake_syncable_service_) { | 73 syncable_service_ptr_factory_(&fake_syncable_service_), |
39 } | 74 mock_attachment_service_(new MockAttachmentService) {} |
40 | 75 |
41 virtual void SetUp() OVERRIDE { | 76 virtual void SetUp() OVERRIDE { |
42 test_user_share_.SetUp(); | 77 test_user_share_.SetUp(); |
43 syncer::ModelTypeSet types = syncer::ProtocolTypes(); | 78 syncer::ModelTypeSet types = syncer::ProtocolTypes(); |
44 for (syncer::ModelTypeSet::Iterator iter = types.First(); iter.Good(); | 79 for (syncer::ModelTypeSet::Iterator iter = types.First(); iter.Good(); |
45 iter.Inc()) { | 80 iter.Inc()) { |
46 syncer::TestUserShare::CreateRoot(iter.Get(), | 81 syncer::TestUserShare::CreateRoot(iter.Get(), |
47 test_user_share_.user_share()); | 82 test_user_share_.user_share()); |
48 } | 83 } |
49 test_user_share_.encryption_handler()->Init(); | 84 test_user_share_.encryption_handler()->Init(); |
| 85 scoped_ptr<MockAttachmentService> mock_attachment_service( |
| 86 new MockAttachmentService); |
| 87 // GenericChangeProcessor takes ownership of the AttachmentService, but we |
| 88 // need to have a pointer to it so we can see that it was used properly. |
| 89 // Take a pointer and trust that GenericChangeProcessor does not prematurely |
| 90 // destroy it. |
| 91 mock_attachment_service_ = mock_attachment_service.get(); |
50 change_processor_.reset(new GenericChangeProcessor( | 92 change_processor_.reset(new GenericChangeProcessor( |
51 &data_type_error_handler_, | 93 &data_type_error_handler_, |
52 syncable_service_ptr_factory_.GetWeakPtr(), | 94 syncable_service_ptr_factory_.GetWeakPtr(), |
53 merge_result_ptr_factory_.GetWeakPtr(), | 95 merge_result_ptr_factory_.GetWeakPtr(), |
54 test_user_share_.user_share(), | 96 test_user_share_.user_share(), |
55 syncer::FakeAttachmentService::CreateForTest())); | 97 mock_attachment_service.PassAs<syncer::AttachmentService>())); |
56 } | 98 } |
57 | 99 |
58 virtual void TearDown() OVERRIDE { | 100 virtual void TearDown() OVERRIDE { |
59 test_user_share_.TearDown(); | 101 test_user_share_.TearDown(); |
60 } | 102 } |
61 | 103 |
62 void BuildChildNodes(int n) { | 104 void BuildChildNodes(int n) { |
63 syncer::WriteTransaction trans(FROM_HERE, user_share()); | 105 syncer::WriteTransaction trans(FROM_HERE, user_share()); |
64 syncer::ReadNode root(&trans); | 106 syncer::ReadNode root(&trans); |
65 ASSERT_EQ(syncer::BaseNode::INIT_OK, | 107 ASSERT_EQ(syncer::BaseNode::INIT_OK, |
66 root.InitByTagLookup(syncer::ModelTypeToRootTag(kType))); | 108 root.InitByTagLookup(syncer::ModelTypeToRootTag(kType))); |
67 for (int i = 0; i < n; ++i) { | 109 for (int i = 0; i < n; ++i) { |
68 syncer::WriteNode node(&trans); | 110 syncer::WriteNode node(&trans); |
69 node.InitUniqueByCreation(kType, root, base::StringPrintf("node%05d", i)); | 111 node.InitUniqueByCreation(kType, root, base::StringPrintf("node%05d", i)); |
70 } | 112 } |
71 } | 113 } |
72 | 114 |
73 GenericChangeProcessor* change_processor() { | 115 GenericChangeProcessor* change_processor() { |
74 return change_processor_.get(); | 116 return change_processor_.get(); |
75 } | 117 } |
76 | 118 |
77 syncer::UserShare* user_share() { | 119 syncer::UserShare* user_share() { |
78 return test_user_share_.user_share(); | 120 return test_user_share_.user_share(); |
79 } | 121 } |
80 | 122 |
| 123 MockAttachmentService* mock_attachment_service() { |
| 124 return mock_attachment_service_; |
| 125 } |
| 126 |
81 private: | 127 private: |
82 base::MessageLoopForUI loop_; | 128 base::MessageLoopForUI loop_; |
83 | 129 |
84 syncer::SyncMergeResult sync_merge_result_; | 130 syncer::SyncMergeResult sync_merge_result_; |
85 base::WeakPtrFactory<syncer::SyncMergeResult> merge_result_ptr_factory_; | 131 base::WeakPtrFactory<syncer::SyncMergeResult> merge_result_ptr_factory_; |
86 | 132 |
87 syncer::FakeSyncableService fake_syncable_service_; | 133 syncer::FakeSyncableService fake_syncable_service_; |
88 base::WeakPtrFactory<syncer::FakeSyncableService> | 134 base::WeakPtrFactory<syncer::FakeSyncableService> |
89 syncable_service_ptr_factory_; | 135 syncable_service_ptr_factory_; |
90 | 136 |
91 DataTypeErrorHandlerMock data_type_error_handler_; | 137 DataTypeErrorHandlerMock data_type_error_handler_; |
92 syncer::TestUserShare test_user_share_; | 138 syncer::TestUserShare test_user_share_; |
| 139 MockAttachmentService* mock_attachment_service_; |
93 | 140 |
94 scoped_ptr<GenericChangeProcessor> change_processor_; | 141 scoped_ptr<GenericChangeProcessor> change_processor_; |
95 }; | 142 }; |
96 | 143 |
97 // Similar to above, but focused on the method that implements sync/api | 144 // Similar to above, but focused on the method that implements sync/api |
98 // interfaces and is hence exposed to datatypes directly. | 145 // interfaces and is hence exposed to datatypes directly. |
99 TEST_F(SyncGenericChangeProcessorTest, StressGetAllSyncData) { | 146 TEST_F(SyncGenericChangeProcessorTest, StressGetAllSyncData) { |
100 const int kNumChildNodes = 1000; | 147 const int kNumChildNodes = 1000; |
101 const int kRepeatCount = 1; | 148 const int kRepeatCount = 1; |
102 | 149 |
(...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
232 base::StringPrintf("tag%i", i)), | 279 base::StringPrintf("tag%i", i)), |
233 syncer::BaseNode::INIT_OK); | 280 syncer::BaseNode::INIT_OK); |
234 ASSERT_EQ(node.GetTitle(), "encrypted"); | 281 ASSERT_EQ(node.GetTitle(), "encrypted"); |
235 const sync_pb::EntitySpecifics& raw_specifics = node.GetEntitySpecifics(); | 282 const sync_pb::EntitySpecifics& raw_specifics = node.GetEntitySpecifics(); |
236 ASSERT_TRUE(raw_specifics.has_password()); | 283 ASSERT_TRUE(raw_specifics.has_password()); |
237 ASSERT_TRUE(raw_specifics.password().has_encrypted()); | 284 ASSERT_TRUE(raw_specifics.password().has_encrypted()); |
238 ASSERT_FALSE(raw_specifics.password().has_client_only_encrypted_data()); | 285 ASSERT_FALSE(raw_specifics.password().has_client_only_encrypted_data()); |
239 } | 286 } |
240 } | 287 } |
241 | 288 |
242 // TODO(maniscalco): Add test cases that verify GenericChangeProcessor calls the | 289 // Verify that attachments on newly added or updated SyncData are passed to the |
243 // right methods on its AttachmentService at the right times (bug 353303). | 290 // AttachmentService. |
| 291 TEST_F(SyncGenericChangeProcessorTest, |
| 292 ProcessSyncChanges_AddUpdateWithAttachment) { |
| 293 std::string tag = "client_tag"; |
| 294 std::string title = "client_title"; |
| 295 sync_pb::EntitySpecifics specifics; |
| 296 sync_pb::PreferenceSpecifics* pref_specifics = specifics.mutable_preference(); |
| 297 pref_specifics->set_name("test"); |
| 298 syncer::AttachmentList attachments; |
| 299 scoped_refptr<base::RefCountedString> attachment_data = |
| 300 new base::RefCountedString; |
| 301 attachment_data->data() = kTestData; |
| 302 attachments.push_back(syncer::Attachment::Create(attachment_data)); |
| 303 attachments.push_back(syncer::Attachment::Create(attachment_data)); |
| 304 |
| 305 // Add a SyncData with two attachments. |
| 306 syncer::SyncChangeList change_list; |
| 307 change_list.push_back( |
| 308 syncer::SyncChange(FROM_HERE, |
| 309 syncer::SyncChange::ACTION_ADD, |
| 310 syncer::SyncData::CreateLocalDataWithAttachments( |
| 311 tag, title, specifics, attachments))); |
| 312 ASSERT_FALSE( |
| 313 change_processor()->ProcessSyncChanges(FROM_HERE, change_list).IsSet()); |
| 314 |
| 315 // Check that the AttachmentService received the new attachments. |
| 316 ASSERT_EQ(mock_attachment_service()->attachment_lists()->size(), 1U); |
| 317 const syncer::AttachmentList& attachments_added = |
| 318 mock_attachment_service()->attachment_lists()->front(); |
| 319 ASSERT_EQ(attachments_added.size(), 2U); |
| 320 ASSERT_EQ(attachments_added[0].GetId(), attachments[0].GetId()); |
| 321 ASSERT_EQ(attachments_added[1].GetId(), attachments[1].GetId()); |
| 322 |
| 323 // Update the SyncData, replacing its two attachments with one new attachment. |
| 324 syncer::AttachmentList new_attachments; |
| 325 new_attachments.push_back(syncer::Attachment::Create(attachment_data)); |
| 326 mock_attachment_service()->attachment_lists()->clear(); |
| 327 change_list.clear(); |
| 328 change_list.push_back( |
| 329 syncer::SyncChange(FROM_HERE, |
| 330 syncer::SyncChange::ACTION_UPDATE, |
| 331 syncer::SyncData::CreateLocalDataWithAttachments( |
| 332 tag, title, specifics, new_attachments))); |
| 333 ASSERT_FALSE( |
| 334 change_processor()->ProcessSyncChanges(FROM_HERE, change_list).IsSet()); |
| 335 |
| 336 // Check that the AttachmentService received it. |
| 337 ASSERT_EQ(mock_attachment_service()->attachment_lists()->size(), 1U); |
| 338 const syncer::AttachmentList& new_attachments_added = |
| 339 mock_attachment_service()->attachment_lists()->front(); |
| 340 ASSERT_EQ(new_attachments_added.size(), 1U); |
| 341 ASSERT_EQ(new_attachments_added[0].GetId(), new_attachments[0].GetId()); |
| 342 } |
244 | 343 |
245 } // namespace | 344 } // namespace |
246 | 345 |
247 } // namespace browser_sync | 346 } // namespace browser_sync |
OLD | NEW |