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" | |
14 #include "sync/api/fake_syncable_service.h" | 13 #include "sync/api/fake_syncable_service.h" |
15 #include "sync/api/sync_change.h" | 14 #include "sync/api/sync_change.h" |
16 #include "sync/api/sync_merge_result.h" | 15 #include "sync/api/sync_merge_result.h" |
17 #include "sync/internal_api/public/base/model_type.h" | 16 #include "sync/internal_api/public/base/model_type.h" |
18 #include "sync/internal_api/public/read_node.h" | 17 #include "sync/internal_api/public/read_node.h" |
19 #include "sync/internal_api/public/read_transaction.h" | 18 #include "sync/internal_api/public/read_transaction.h" |
20 #include "sync/internal_api/public/sync_encryption_handler.h" | 19 #include "sync/internal_api/public/sync_encryption_handler.h" |
21 #include "sync/internal_api/public/test/test_user_share.h" | 20 #include "sync/internal_api/public/test/test_user_share.h" |
22 #include "sync/internal_api/public/user_share.h" | 21 #include "sync/internal_api/public/user_share.h" |
23 #include "sync/internal_api/public/write_node.h" | 22 #include "sync/internal_api/public/write_node.h" |
24 #include "sync/internal_api/public/write_transaction.h" | 23 #include "sync/internal_api/public/write_transaction.h" |
25 #include "testing/gtest/include/gtest/gtest.h" | 24 #include "testing/gtest/include/gtest/gtest.h" |
26 | 25 |
27 namespace browser_sync { | 26 namespace browser_sync { |
28 | 27 |
29 namespace { | 28 namespace { |
30 | 29 |
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 | |
65 class SyncGenericChangeProcessorTest : public testing::Test { | 30 class SyncGenericChangeProcessorTest : public testing::Test { |
66 public: | 31 public: |
67 // It doesn't matter which type we use. Just pick one. | 32 // It doesn't matter which type we use. Just pick one. |
68 static const syncer::ModelType kType = syncer::PREFERENCES; | 33 static const syncer::ModelType kType = syncer::PREFERENCES; |
69 | 34 |
70 SyncGenericChangeProcessorTest() | 35 SyncGenericChangeProcessorTest() : |
71 : sync_merge_result_(kType), | 36 sync_merge_result_(kType), |
72 merge_result_ptr_factory_(&sync_merge_result_), | 37 merge_result_ptr_factory_(&sync_merge_result_), |
73 syncable_service_ptr_factory_(&fake_syncable_service_), | 38 syncable_service_ptr_factory_(&fake_syncable_service_) { |
74 mock_attachment_service_(new MockAttachmentService) {} | 39 } |
75 | 40 |
76 virtual void SetUp() OVERRIDE { | 41 virtual void SetUp() OVERRIDE { |
77 test_user_share_.SetUp(); | 42 test_user_share_.SetUp(); |
78 syncer::ModelTypeSet types = syncer::ProtocolTypes(); | 43 syncer::ModelTypeSet types = syncer::ProtocolTypes(); |
79 for (syncer::ModelTypeSet::Iterator iter = types.First(); iter.Good(); | 44 for (syncer::ModelTypeSet::Iterator iter = types.First(); iter.Good(); |
80 iter.Inc()) { | 45 iter.Inc()) { |
81 syncer::TestUserShare::CreateRoot(iter.Get(), | 46 syncer::TestUserShare::CreateRoot(iter.Get(), |
82 test_user_share_.user_share()); | 47 test_user_share_.user_share()); |
83 } | 48 } |
84 test_user_share_.encryption_handler()->Init(); | 49 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(); | |
92 change_processor_.reset(new GenericChangeProcessor( | 50 change_processor_.reset(new GenericChangeProcessor( |
93 &data_type_error_handler_, | 51 &data_type_error_handler_, |
94 syncable_service_ptr_factory_.GetWeakPtr(), | 52 syncable_service_ptr_factory_.GetWeakPtr(), |
95 merge_result_ptr_factory_.GetWeakPtr(), | 53 merge_result_ptr_factory_.GetWeakPtr(), |
96 test_user_share_.user_share(), | 54 test_user_share_.user_share(), |
97 mock_attachment_service.PassAs<syncer::AttachmentService>())); | 55 syncer::FakeAttachmentService::CreateForTest())); |
98 } | 56 } |
99 | 57 |
100 virtual void TearDown() OVERRIDE { | 58 virtual void TearDown() OVERRIDE { |
101 test_user_share_.TearDown(); | 59 test_user_share_.TearDown(); |
102 } | 60 } |
103 | 61 |
104 void BuildChildNodes(int n) { | 62 void BuildChildNodes(int n) { |
105 syncer::WriteTransaction trans(FROM_HERE, user_share()); | 63 syncer::WriteTransaction trans(FROM_HERE, user_share()); |
106 syncer::ReadNode root(&trans); | 64 syncer::ReadNode root(&trans); |
107 ASSERT_EQ(syncer::BaseNode::INIT_OK, | 65 ASSERT_EQ(syncer::BaseNode::INIT_OK, |
108 root.InitByTagLookup(syncer::ModelTypeToRootTag(kType))); | 66 root.InitByTagLookup(syncer::ModelTypeToRootTag(kType))); |
109 for (int i = 0; i < n; ++i) { | 67 for (int i = 0; i < n; ++i) { |
110 syncer::WriteNode node(&trans); | 68 syncer::WriteNode node(&trans); |
111 node.InitUniqueByCreation(kType, root, base::StringPrintf("node%05d", i)); | 69 node.InitUniqueByCreation(kType, root, base::StringPrintf("node%05d", i)); |
112 } | 70 } |
113 } | 71 } |
114 | 72 |
115 GenericChangeProcessor* change_processor() { | 73 GenericChangeProcessor* change_processor() { |
116 return change_processor_.get(); | 74 return change_processor_.get(); |
117 } | 75 } |
118 | 76 |
119 syncer::UserShare* user_share() { | 77 syncer::UserShare* user_share() { |
120 return test_user_share_.user_share(); | 78 return test_user_share_.user_share(); |
121 } | 79 } |
122 | 80 |
123 MockAttachmentService* mock_attachment_service() { | |
124 return mock_attachment_service_; | |
125 } | |
126 | |
127 private: | 81 private: |
128 base::MessageLoopForUI loop_; | 82 base::MessageLoopForUI loop_; |
129 | 83 |
130 syncer::SyncMergeResult sync_merge_result_; | 84 syncer::SyncMergeResult sync_merge_result_; |
131 base::WeakPtrFactory<syncer::SyncMergeResult> merge_result_ptr_factory_; | 85 base::WeakPtrFactory<syncer::SyncMergeResult> merge_result_ptr_factory_; |
132 | 86 |
133 syncer::FakeSyncableService fake_syncable_service_; | 87 syncer::FakeSyncableService fake_syncable_service_; |
134 base::WeakPtrFactory<syncer::FakeSyncableService> | 88 base::WeakPtrFactory<syncer::FakeSyncableService> |
135 syncable_service_ptr_factory_; | 89 syncable_service_ptr_factory_; |
136 | 90 |
137 DataTypeErrorHandlerMock data_type_error_handler_; | 91 DataTypeErrorHandlerMock data_type_error_handler_; |
138 syncer::TestUserShare test_user_share_; | 92 syncer::TestUserShare test_user_share_; |
139 MockAttachmentService* mock_attachment_service_; | |
140 | 93 |
141 scoped_ptr<GenericChangeProcessor> change_processor_; | 94 scoped_ptr<GenericChangeProcessor> change_processor_; |
142 }; | 95 }; |
143 | 96 |
144 // Similar to above, but focused on the method that implements sync/api | 97 // Similar to above, but focused on the method that implements sync/api |
145 // interfaces and is hence exposed to datatypes directly. | 98 // interfaces and is hence exposed to datatypes directly. |
146 TEST_F(SyncGenericChangeProcessorTest, StressGetAllSyncData) { | 99 TEST_F(SyncGenericChangeProcessorTest, StressGetAllSyncData) { |
147 const int kNumChildNodes = 1000; | 100 const int kNumChildNodes = 1000; |
148 const int kRepeatCount = 1; | 101 const int kRepeatCount = 1; |
149 | 102 |
(...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
279 base::StringPrintf("tag%i", i)), | 232 base::StringPrintf("tag%i", i)), |
280 syncer::BaseNode::INIT_OK); | 233 syncer::BaseNode::INIT_OK); |
281 ASSERT_EQ(node.GetTitle(), "encrypted"); | 234 ASSERT_EQ(node.GetTitle(), "encrypted"); |
282 const sync_pb::EntitySpecifics& raw_specifics = node.GetEntitySpecifics(); | 235 const sync_pb::EntitySpecifics& raw_specifics = node.GetEntitySpecifics(); |
283 ASSERT_TRUE(raw_specifics.has_password()); | 236 ASSERT_TRUE(raw_specifics.has_password()); |
284 ASSERT_TRUE(raw_specifics.password().has_encrypted()); | 237 ASSERT_TRUE(raw_specifics.password().has_encrypted()); |
285 ASSERT_FALSE(raw_specifics.password().has_client_only_encrypted_data()); | 238 ASSERT_FALSE(raw_specifics.password().has_client_only_encrypted_data()); |
286 } | 239 } |
287 } | 240 } |
288 | 241 |
289 // Verify that attachments on newly added or updated SyncData are passed to the | 242 // TODO(maniscalco): Add test cases that verify GenericChangeProcessor calls the |
290 // AttachmentService. | 243 // right methods on its AttachmentService at the right times (bug 353303). |
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 } | |
343 | 244 |
344 } // namespace | 245 } // namespace |
345 | 246 |
346 } // namespace browser_sync | 247 } // namespace browser_sync |
OLD | NEW |