Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(272)

Side by Side Diff: components/sync_driver/generic_change_processor_unittest.cc

Issue 2203673002: [Sync] Move //components/sync_driver to //components/sync/driver. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@sd-a
Patch Set: Full change rebased on static lib. Created 4 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
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.
4
5 #include "components/sync_driver/generic_change_processor.h"
6
7 #include <stddef.h>
8
9 #include <memory>
10 #include <string>
11 #include <utility>
12
13 #include "base/memory/weak_ptr.h"
14 #include "base/message_loop/message_loop.h"
15 #include "base/run_loop.h"
16 #include "base/strings/stringprintf.h"
17 #include "components/sync/api/attachments/attachment_id.h"
18 #include "components/sync/api/attachments/attachment_store.h"
19 #include "components/sync/api/fake_syncable_service.h"
20 #include "components/sync/api/sync_change.h"
21 #include "components/sync/api/sync_merge_result.h"
22 #include "components/sync/base/model_type.h"
23 #include "components/sync/core/attachments/attachment_service_impl.h"
24 #include "components/sync/core/attachments/fake_attachment_downloader.h"
25 #include "components/sync/core/attachments/fake_attachment_uploader.h"
26 #include "components/sync/core/read_node.h"
27 #include "components/sync/core/read_transaction.h"
28 #include "components/sync/core/sync_encryption_handler.h"
29 #include "components/sync/core/test/data_type_error_handler_mock.h"
30 #include "components/sync/core/test/test_user_share.h"
31 #include "components/sync/core/user_share.h"
32 #include "components/sync/core/write_node.h"
33 #include "components/sync/core/write_transaction.h"
34 #include "components/sync_driver/fake_sync_client.h"
35 #include "components/sync_driver/local_device_info_provider.h"
36 #include "components/sync_driver/sync_api_component_factory.h"
37 #include "testing/gmock/include/gmock/gmock.h"
38 #include "testing/gtest/include/gtest/gtest.h"
39
40 namespace sync_driver {
41
42 namespace {
43
44 // A mock that keeps track of attachments passed to UploadAttachments.
45 class MockAttachmentService : public syncer::AttachmentServiceImpl {
46 public:
47 MockAttachmentService(
48 std::unique_ptr<syncer::AttachmentStoreForSync> attachment_store);
49 ~MockAttachmentService() override;
50 void UploadAttachments(
51 const syncer::AttachmentIdList& attachment_ids) override;
52 std::vector<syncer::AttachmentIdList>* attachment_id_lists();
53
54 private:
55 std::vector<syncer::AttachmentIdList> attachment_id_lists_;
56 };
57
58 MockAttachmentService::MockAttachmentService(
59 std::unique_ptr<syncer::AttachmentStoreForSync> attachment_store)
60 : AttachmentServiceImpl(std::move(attachment_store),
61 std::unique_ptr<syncer::AttachmentUploader>(
62 new syncer::FakeAttachmentUploader),
63 std::unique_ptr<syncer::AttachmentDownloader>(
64 new syncer::FakeAttachmentDownloader),
65 NULL,
66 base::TimeDelta(),
67 base::TimeDelta()) {}
68
69 MockAttachmentService::~MockAttachmentService() {
70 }
71
72 void MockAttachmentService::UploadAttachments(
73 const syncer::AttachmentIdList& attachment_ids) {
74 attachment_id_lists_.push_back(attachment_ids);
75 AttachmentServiceImpl::UploadAttachments(attachment_ids);
76 }
77
78 std::vector<syncer::AttachmentIdList>*
79 MockAttachmentService::attachment_id_lists() {
80 return &attachment_id_lists_;
81 }
82
83 // MockSyncApiComponentFactory needed to initialize GenericChangeProcessor and
84 // pass MockAttachmentService to it.
85 class MockSyncApiComponentFactory : public SyncApiComponentFactory {
86 public:
87 MockSyncApiComponentFactory() {}
88
89 // SyncApiComponentFactory implementation.
90 void RegisterDataTypes(
91 sync_driver::SyncService* sync_service,
92 const RegisterDataTypesMethod& register_platform_types_method) override {}
93 sync_driver::DataTypeManager* CreateDataTypeManager(
94 const syncer::WeakHandle<syncer::DataTypeDebugInfoListener>&
95 debug_info_listener,
96 const sync_driver::DataTypeController::TypeMap* controllers,
97 const sync_driver::DataTypeEncryptionHandler* encryption_handler,
98 browser_sync::SyncBackendHost* backend,
99 sync_driver::DataTypeManagerObserver* observer) override{
100 return nullptr;
101 };
102 browser_sync::SyncBackendHost* CreateSyncBackendHost(
103 const std::string& name,
104 invalidation::InvalidationService* invalidator,
105 const base::WeakPtr<sync_driver::SyncPrefs>& sync_prefs,
106 const base::FilePath& sync_folder) override {
107 return nullptr;
108 }
109 std::unique_ptr<sync_driver::LocalDeviceInfoProvider>
110 CreateLocalDeviceInfoProvider() override {
111 return nullptr;
112 }
113 SyncComponents CreateBookmarkSyncComponents(
114 sync_driver::SyncService* sync_service,
115 syncer::DataTypeErrorHandler* error_handler) override {
116 return SyncComponents(nullptr, nullptr);
117 }
118
119 std::unique_ptr<syncer::AttachmentService> CreateAttachmentService(
120 std::unique_ptr<syncer::AttachmentStoreForSync> attachment_store,
121 const syncer::UserShare& user_share,
122 const std::string& store_birthday,
123 syncer::ModelType model_type,
124 syncer::AttachmentService::Delegate* delegate) override {
125 std::unique_ptr<MockAttachmentService> attachment_service(
126 new MockAttachmentService(std::move(attachment_store)));
127 // GenericChangeProcessor takes ownership of the AttachmentService, but we
128 // need to have a pointer to it so we can see that it was used properly.
129 // Take a pointer and trust that GenericChangeProcessor does not prematurely
130 // destroy it.
131 mock_attachment_service_ = attachment_service.get();
132 return std::move(attachment_service);
133 }
134
135 MockAttachmentService* GetMockAttachmentService() {
136 return mock_attachment_service_;
137 }
138
139 private:
140 MockAttachmentService* mock_attachment_service_;
141 };
142
143 class SyncGenericChangeProcessorTest : public testing::Test {
144 public:
145 // Most test cases will use this type. For those that need a
146 // GenericChangeProcessor for a different type, use |InitializeForType|.
147 static const syncer::ModelType kType = syncer::PREFERENCES;
148
149 SyncGenericChangeProcessorTest()
150 : syncable_service_ptr_factory_(&fake_syncable_service_),
151 mock_attachment_service_(NULL),
152 sync_client_(&sync_factory_) {}
153
154 void SetUp() override {
155 // Use kType by default, but allow test cases to re-initialize with whatever
156 // type they choose. Therefore, it's important that all type dependent
157 // initialization occurs in InitializeForType.
158 InitializeForType(kType);
159 }
160
161 void TearDown() override {
162 mock_attachment_service_ = NULL;
163 if (test_user_share_) {
164 test_user_share_->TearDown();
165 }
166 }
167
168 // Initialize GenericChangeProcessor and related classes for testing with
169 // model type |type|.
170 void InitializeForType(syncer::ModelType type) {
171 TearDown();
172 test_user_share_.reset(new syncer::TestUserShare);
173 test_user_share_->SetUp();
174 sync_merge_result_.reset(new syncer::SyncMergeResult(type));
175 merge_result_ptr_factory_.reset(
176 new base::WeakPtrFactory<syncer::SyncMergeResult>(
177 sync_merge_result_.get()));
178
179 syncer::ModelTypeSet types = syncer::ProtocolTypes();
180 for (syncer::ModelTypeSet::Iterator iter = types.First(); iter.Good();
181 iter.Inc()) {
182 syncer::TestUserShare::CreateRoot(iter.Get(),
183 test_user_share_->user_share());
184 }
185 test_user_share_->encryption_handler()->Init();
186 ConstructGenericChangeProcessor(type);
187 }
188
189 void ConstructGenericChangeProcessor(syncer::ModelType type) {
190 std::unique_ptr<syncer::AttachmentStore> attachment_store =
191 syncer::AttachmentStore::CreateInMemoryStore();
192 change_processor_.reset(new GenericChangeProcessor(
193 type, &data_type_error_handler_,
194 syncable_service_ptr_factory_.GetWeakPtr(),
195 merge_result_ptr_factory_->GetWeakPtr(), test_user_share_->user_share(),
196 &sync_client_, attachment_store->CreateAttachmentStoreForSync()));
197 mock_attachment_service_ = sync_factory_.GetMockAttachmentService();
198 }
199
200 void BuildChildNodes(syncer::ModelType type, int n) {
201 syncer::WriteTransaction trans(FROM_HERE, user_share());
202 for (int i = 0; i < n; ++i) {
203 syncer::WriteNode node(&trans);
204 node.InitUniqueByCreation(type, base::StringPrintf("node%05d", i));
205 }
206 }
207
208 GenericChangeProcessor* change_processor() {
209 return change_processor_.get();
210 }
211
212 syncer::UserShare* user_share() {
213 return test_user_share_->user_share();
214 }
215
216 MockAttachmentService* mock_attachment_service() {
217 return mock_attachment_service_;
218 }
219
220 void RunLoop() {
221 base::RunLoop run_loop;
222 run_loop.RunUntilIdle();
223 }
224
225 private:
226 base::MessageLoopForUI loop_;
227
228 std::unique_ptr<syncer::SyncMergeResult> sync_merge_result_;
229 std::unique_ptr<base::WeakPtrFactory<syncer::SyncMergeResult>>
230 merge_result_ptr_factory_;
231
232 syncer::FakeSyncableService fake_syncable_service_;
233 base::WeakPtrFactory<syncer::FakeSyncableService>
234 syncable_service_ptr_factory_;
235
236 syncer::DataTypeErrorHandlerMock data_type_error_handler_;
237 std::unique_ptr<syncer::TestUserShare> test_user_share_;
238 MockAttachmentService* mock_attachment_service_;
239 FakeSyncClient sync_client_;
240 MockSyncApiComponentFactory sync_factory_;
241
242 std::unique_ptr<GenericChangeProcessor> change_processor_;
243 };
244
245 // Similar to above, but focused on the method that implements sync/api
246 // interfaces and is hence exposed to datatypes directly.
247 TEST_F(SyncGenericChangeProcessorTest, StressGetAllSyncData) {
248 const int kNumChildNodes = 1000;
249 const int kRepeatCount = 1;
250
251 ASSERT_NO_FATAL_FAILURE(BuildChildNodes(kType, kNumChildNodes));
252
253 for (int i = 0; i < kRepeatCount; ++i) {
254 syncer::SyncDataList sync_data =
255 change_processor()->GetAllSyncData(kType);
256
257 // Start with a simple test. We can add more in-depth testing later.
258 EXPECT_EQ(static_cast<size_t>(kNumChildNodes), sync_data.size());
259 }
260 }
261
262 TEST_F(SyncGenericChangeProcessorTest, SetGetPasswords) {
263 InitializeForType(syncer::PASSWORDS);
264 const int kNumPasswords = 10;
265 sync_pb::PasswordSpecificsData password_data;
266 password_data.set_username_value("user");
267
268 sync_pb::EntitySpecifics password_holder;
269
270 syncer::SyncChangeList change_list;
271 for (int i = 0; i < kNumPasswords; ++i) {
272 password_data.set_password_value(
273 base::StringPrintf("password%i", i));
274 password_holder.mutable_password()->mutable_client_only_encrypted_data()->
275 CopyFrom(password_data);
276 change_list.push_back(
277 syncer::SyncChange(FROM_HERE,
278 syncer::SyncChange::ACTION_ADD,
279 syncer::SyncData::CreateLocalData(
280 base::StringPrintf("tag%i", i),
281 base::StringPrintf("title%i", i),
282 password_holder)));
283 }
284
285 ASSERT_FALSE(
286 change_processor()->ProcessSyncChanges(FROM_HERE, change_list).IsSet());
287
288 syncer::SyncDataList password_list(
289 change_processor()->GetAllSyncData(syncer::PASSWORDS));
290
291 ASSERT_EQ(password_list.size(), change_list.size());
292 for (int i = 0; i < kNumPasswords; ++i) {
293 // Verify the password is returned properly.
294 ASSERT_TRUE(password_list[i].GetSpecifics().has_password());
295 ASSERT_TRUE(password_list[i].GetSpecifics().password().
296 has_client_only_encrypted_data());
297 ASSERT_FALSE(password_list[i].GetSpecifics().password().has_encrypted());
298 const sync_pb::PasswordSpecificsData& sync_password =
299 password_list[i].GetSpecifics().password().client_only_encrypted_data();
300 const sync_pb::PasswordSpecificsData& change_password =
301 change_list[i].sync_data().GetSpecifics().password().
302 client_only_encrypted_data();
303 ASSERT_EQ(sync_password.password_value(), change_password.password_value());
304 ASSERT_EQ(sync_password.username_value(), change_password.username_value());
305
306 // Verify the raw sync data was stored securely.
307 syncer::ReadTransaction read_transaction(FROM_HERE, user_share());
308 syncer::ReadNode node(&read_transaction);
309 ASSERT_EQ(node.InitByClientTagLookup(syncer::PASSWORDS,
310 base::StringPrintf("tag%i", i)),
311 syncer::BaseNode::INIT_OK);
312 ASSERT_EQ(node.GetTitle(), "encrypted");
313 const sync_pb::EntitySpecifics& raw_specifics = node.GetEntitySpecifics();
314 ASSERT_TRUE(raw_specifics.has_password());
315 ASSERT_TRUE(raw_specifics.password().has_encrypted());
316 ASSERT_FALSE(raw_specifics.password().has_client_only_encrypted_data());
317 }
318 }
319
320 TEST_F(SyncGenericChangeProcessorTest, UpdatePasswords) {
321 InitializeForType(syncer::PASSWORDS);
322 const int kNumPasswords = 10;
323 sync_pb::PasswordSpecificsData password_data;
324 password_data.set_username_value("user");
325
326 sync_pb::EntitySpecifics password_holder;
327
328 syncer::SyncChangeList change_list;
329 syncer::SyncChangeList change_list2;
330 for (int i = 0; i < kNumPasswords; ++i) {
331 password_data.set_password_value(
332 base::StringPrintf("password%i", i));
333 password_holder.mutable_password()->mutable_client_only_encrypted_data()->
334 CopyFrom(password_data);
335 change_list.push_back(
336 syncer::SyncChange(FROM_HERE,
337 syncer::SyncChange::ACTION_ADD,
338 syncer::SyncData::CreateLocalData(
339 base::StringPrintf("tag%i", i),
340 base::StringPrintf("title%i", i),
341 password_holder)));
342 password_data.set_password_value(
343 base::StringPrintf("password_m%i", i));
344 password_holder.mutable_password()->mutable_client_only_encrypted_data()->
345 CopyFrom(password_data);
346 change_list2.push_back(
347 syncer::SyncChange(FROM_HERE,
348 syncer::SyncChange::ACTION_UPDATE,
349 syncer::SyncData::CreateLocalData(
350 base::StringPrintf("tag%i", i),
351 base::StringPrintf("title_m%i", i),
352 password_holder)));
353 }
354
355 ASSERT_FALSE(
356 change_processor()->ProcessSyncChanges(FROM_HERE, change_list).IsSet());
357 ASSERT_FALSE(
358 change_processor()->ProcessSyncChanges(FROM_HERE, change_list2).IsSet());
359
360 syncer::SyncDataList password_list(
361 change_processor()->GetAllSyncData(syncer::PASSWORDS));
362
363 ASSERT_EQ(password_list.size(), change_list2.size());
364 for (int i = 0; i < kNumPasswords; ++i) {
365 // Verify the password is returned properly.
366 ASSERT_TRUE(password_list[i].GetSpecifics().has_password());
367 ASSERT_TRUE(password_list[i].GetSpecifics().password().
368 has_client_only_encrypted_data());
369 ASSERT_FALSE(password_list[i].GetSpecifics().password().has_encrypted());
370 const sync_pb::PasswordSpecificsData& sync_password =
371 password_list[i].GetSpecifics().password().client_only_encrypted_data();
372 const sync_pb::PasswordSpecificsData& change_password =
373 change_list2[i].sync_data().GetSpecifics().password().
374 client_only_encrypted_data();
375 ASSERT_EQ(sync_password.password_value(), change_password.password_value());
376 ASSERT_EQ(sync_password.username_value(), change_password.username_value());
377
378 // Verify the raw sync data was stored securely.
379 syncer::ReadTransaction read_transaction(FROM_HERE, user_share());
380 syncer::ReadNode node(&read_transaction);
381 ASSERT_EQ(node.InitByClientTagLookup(syncer::PASSWORDS,
382 base::StringPrintf("tag%i", i)),
383 syncer::BaseNode::INIT_OK);
384 ASSERT_EQ(node.GetTitle(), "encrypted");
385 const sync_pb::EntitySpecifics& raw_specifics = node.GetEntitySpecifics();
386 ASSERT_TRUE(raw_specifics.has_password());
387 ASSERT_TRUE(raw_specifics.password().has_encrypted());
388 ASSERT_FALSE(raw_specifics.password().has_client_only_encrypted_data());
389 }
390 }
391
392 // Verify that attachments on newly added or updated SyncData are passed to the
393 // AttachmentService.
394 TEST_F(SyncGenericChangeProcessorTest,
395 ProcessSyncChanges_AddUpdateWithAttachment) {
396 std::string tag = "client_tag";
397 std::string title = "client_title";
398 sync_pb::EntitySpecifics specifics;
399 sync_pb::PreferenceSpecifics* pref_specifics = specifics.mutable_preference();
400 pref_specifics->set_name("test");
401
402 syncer::AttachmentIdList attachment_ids;
403 attachment_ids.push_back(syncer::AttachmentId::Create(0, 0));
404 attachment_ids.push_back(syncer::AttachmentId::Create(0, 0));
405
406 // Add a SyncData with two attachments.
407 syncer::SyncChangeList change_list;
408 change_list.push_back(
409 syncer::SyncChange(FROM_HERE,
410 syncer::SyncChange::ACTION_ADD,
411 syncer::SyncData::CreateLocalDataWithAttachments(
412 tag, title, specifics, attachment_ids)));
413 ASSERT_FALSE(
414 change_processor()->ProcessSyncChanges(FROM_HERE, change_list).IsSet());
415 RunLoop();
416
417 // Check that the AttachmentService received the new attachments.
418 ASSERT_EQ(mock_attachment_service()->attachment_id_lists()->size(), 1U);
419 const syncer::AttachmentIdList& attachments_added =
420 mock_attachment_service()->attachment_id_lists()->front();
421 ASSERT_THAT(
422 attachments_added,
423 testing::UnorderedElementsAre(attachment_ids[0], attachment_ids[1]));
424
425 // Update the SyncData, replacing its two attachments with one new attachment.
426 syncer::AttachmentIdList new_attachment_ids;
427 new_attachment_ids.push_back(syncer::AttachmentId::Create(0, 0));
428 mock_attachment_service()->attachment_id_lists()->clear();
429 change_list.clear();
430 change_list.push_back(
431 syncer::SyncChange(FROM_HERE,
432 syncer::SyncChange::ACTION_UPDATE,
433 syncer::SyncData::CreateLocalDataWithAttachments(
434 tag, title, specifics, new_attachment_ids)));
435 ASSERT_FALSE(
436 change_processor()->ProcessSyncChanges(FROM_HERE, change_list).IsSet());
437 RunLoop();
438
439 // Check that the AttachmentService received it.
440 ASSERT_EQ(mock_attachment_service()->attachment_id_lists()->size(), 1U);
441 const syncer::AttachmentIdList& new_attachments_added =
442 mock_attachment_service()->attachment_id_lists()->front();
443 ASSERT_THAT(new_attachments_added,
444 testing::UnorderedElementsAre(new_attachment_ids[0]));
445 }
446
447 // Verify that after attachment is uploaded GenericChangeProcessor updates
448 // corresponding entries
449 TEST_F(SyncGenericChangeProcessorTest, AttachmentUploaded) {
450 std::string tag = "client_tag";
451 std::string title = "client_title";
452 sync_pb::EntitySpecifics specifics;
453 sync_pb::PreferenceSpecifics* pref_specifics = specifics.mutable_preference();
454 pref_specifics->set_name("test");
455
456 syncer::AttachmentIdList attachment_ids;
457 attachment_ids.push_back(syncer::AttachmentId::Create(0, 0));
458
459 // Add a SyncData with two attachments.
460 syncer::SyncChangeList change_list;
461 change_list.push_back(
462 syncer::SyncChange(FROM_HERE,
463 syncer::SyncChange::ACTION_ADD,
464 syncer::SyncData::CreateLocalDataWithAttachments(
465 tag, title, specifics, attachment_ids)));
466 ASSERT_FALSE(
467 change_processor()->ProcessSyncChanges(FROM_HERE, change_list).IsSet());
468
469 sync_pb::AttachmentIdProto attachment_id_proto = attachment_ids[0].GetProto();
470 syncer::AttachmentId attachment_id =
471 syncer::AttachmentId::CreateFromProto(attachment_id_proto);
472
473 change_processor()->OnAttachmentUploaded(attachment_id);
474 syncer::ReadTransaction read_transaction(FROM_HERE, user_share());
475 syncer::ReadNode node(&read_transaction);
476 ASSERT_EQ(node.InitByClientTagLookup(kType, tag), syncer::BaseNode::INIT_OK);
477 attachment_ids = node.GetAttachmentIds();
478 EXPECT_EQ(1U, attachment_ids.size());
479 }
480
481 // Verify that upon construction, all attachments not yet on the server are
482 // scheduled for upload.
483 TEST_F(SyncGenericChangeProcessorTest, UploadAllAttachmentsNotOnServer) {
484 // Create two attachment ids. id2 will be marked as "on server".
485 syncer::AttachmentId id1 = syncer::AttachmentId::Create(0, 0);
486 syncer::AttachmentId id2 = syncer::AttachmentId::Create(0, 0);
487 {
488 // Write an entry containing these two attachment ids.
489 syncer::WriteTransaction trans(FROM_HERE, user_share());
490 syncer::ReadNode root(&trans);
491 ASSERT_EQ(syncer::BaseNode::INIT_OK, root.InitTypeRoot(kType));
492 syncer::WriteNode node(&trans);
493 node.InitUniqueByCreation(kType, root, "some node");
494 sync_pb::AttachmentMetadata metadata;
495 sync_pb::AttachmentMetadataRecord* record1 = metadata.add_record();
496 *record1->mutable_id() = id1.GetProto();
497 sync_pb::AttachmentMetadataRecord* record2 = metadata.add_record();
498 *record2->mutable_id() = id2.GetProto();
499 record2->set_is_on_server(true);
500 node.SetAttachmentMetadata(metadata);
501 }
502
503 // Construct the GenericChangeProcessor and see that it asks the
504 // AttachmentService to upload id1 only.
505 ConstructGenericChangeProcessor(kType);
506 ASSERT_EQ(1U, mock_attachment_service()->attachment_id_lists()->size());
507 ASSERT_THAT(mock_attachment_service()->attachment_id_lists()->front(),
508 testing::UnorderedElementsAre(id1));
509 }
510
511 // Test that attempting to add an entry that already exists still works.
512 TEST_F(SyncGenericChangeProcessorTest, AddExistingEntry) {
513 InitializeForType(syncer::SESSIONS);
514 sync_pb::EntitySpecifics sessions_specifics;
515 sessions_specifics.mutable_session()->set_session_tag("session tag");
516 syncer::SyncChangeList changes;
517
518 // First add it normally.
519 changes.push_back(syncer::SyncChange(
520 FROM_HERE, syncer::SyncChange::ACTION_ADD,
521 syncer::SyncData::CreateLocalData(base::StringPrintf("tag"),
522 base::StringPrintf("title"),
523 sessions_specifics)));
524 ASSERT_FALSE(
525 change_processor()->ProcessSyncChanges(FROM_HERE, changes).IsSet());
526
527 // Now attempt to add it again, but with different specifics. Should not
528 // result in an error and should still update the specifics.
529 sessions_specifics.mutable_session()->set_session_tag("session tag 2");
530 changes[0] =
531 syncer::SyncChange(FROM_HERE, syncer::SyncChange::ACTION_ADD,
532 syncer::SyncData::CreateLocalData(
533 base::StringPrintf("tag"),
534 base::StringPrintf("title"), sessions_specifics));
535 ASSERT_FALSE(
536 change_processor()->ProcessSyncChanges(FROM_HERE, changes).IsSet());
537
538 // Verify the data was updated properly.
539 syncer::SyncDataList sync_data =
540 change_processor()->GetAllSyncData(syncer::SESSIONS);
541 ASSERT_EQ(sync_data.size(), 1U);
542 ASSERT_EQ("session tag 2",
543 sync_data[0].GetSpecifics().session().session_tag());
544 EXPECT_FALSE(syncer::SyncDataRemote(sync_data[0]).GetClientTagHash().empty());
545 }
546
547 } // namespace
548
549 } // namespace sync_driver
OLDNEW
« no previous file with comments | « components/sync_driver/generic_change_processor_factory.cc ('k') | components/sync_driver/glue/browser_thread_model_worker.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698