Index: components/sync_driver/generic_change_processor_unittest.cc |
diff --git a/components/sync_driver/generic_change_processor_unittest.cc b/components/sync_driver/generic_change_processor_unittest.cc |
deleted file mode 100644 |
index dfaf95a355dc9ce7f569a3fa419eaede852218ec..0000000000000000000000000000000000000000 |
--- a/components/sync_driver/generic_change_processor_unittest.cc |
+++ /dev/null |
@@ -1,549 +0,0 @@ |
-// Copyright 2014 The Chromium Authors. All rights reserved. |
-// Use of this source code is governed by a BSD-style license that can be |
-// found in the LICENSE file. |
- |
-#include "components/sync_driver/generic_change_processor.h" |
- |
-#include <stddef.h> |
- |
-#include <memory> |
-#include <string> |
-#include <utility> |
- |
-#include "base/memory/weak_ptr.h" |
-#include "base/message_loop/message_loop.h" |
-#include "base/run_loop.h" |
-#include "base/strings/stringprintf.h" |
-#include "components/sync/api/attachments/attachment_id.h" |
-#include "components/sync/api/attachments/attachment_store.h" |
-#include "components/sync/api/fake_syncable_service.h" |
-#include "components/sync/api/sync_change.h" |
-#include "components/sync/api/sync_merge_result.h" |
-#include "components/sync/base/model_type.h" |
-#include "components/sync/core/attachments/attachment_service_impl.h" |
-#include "components/sync/core/attachments/fake_attachment_downloader.h" |
-#include "components/sync/core/attachments/fake_attachment_uploader.h" |
-#include "components/sync/core/read_node.h" |
-#include "components/sync/core/read_transaction.h" |
-#include "components/sync/core/sync_encryption_handler.h" |
-#include "components/sync/core/test/data_type_error_handler_mock.h" |
-#include "components/sync/core/test/test_user_share.h" |
-#include "components/sync/core/user_share.h" |
-#include "components/sync/core/write_node.h" |
-#include "components/sync/core/write_transaction.h" |
-#include "components/sync_driver/fake_sync_client.h" |
-#include "components/sync_driver/local_device_info_provider.h" |
-#include "components/sync_driver/sync_api_component_factory.h" |
-#include "testing/gmock/include/gmock/gmock.h" |
-#include "testing/gtest/include/gtest/gtest.h" |
- |
-namespace sync_driver { |
- |
-namespace { |
- |
-// A mock that keeps track of attachments passed to UploadAttachments. |
-class MockAttachmentService : public syncer::AttachmentServiceImpl { |
- public: |
- MockAttachmentService( |
- std::unique_ptr<syncer::AttachmentStoreForSync> attachment_store); |
- ~MockAttachmentService() override; |
- void UploadAttachments( |
- const syncer::AttachmentIdList& attachment_ids) override; |
- std::vector<syncer::AttachmentIdList>* attachment_id_lists(); |
- |
- private: |
- std::vector<syncer::AttachmentIdList> attachment_id_lists_; |
-}; |
- |
-MockAttachmentService::MockAttachmentService( |
- std::unique_ptr<syncer::AttachmentStoreForSync> attachment_store) |
- : AttachmentServiceImpl(std::move(attachment_store), |
- std::unique_ptr<syncer::AttachmentUploader>( |
- new syncer::FakeAttachmentUploader), |
- std::unique_ptr<syncer::AttachmentDownloader>( |
- new syncer::FakeAttachmentDownloader), |
- NULL, |
- base::TimeDelta(), |
- base::TimeDelta()) {} |
- |
-MockAttachmentService::~MockAttachmentService() { |
-} |
- |
-void MockAttachmentService::UploadAttachments( |
- const syncer::AttachmentIdList& attachment_ids) { |
- attachment_id_lists_.push_back(attachment_ids); |
- AttachmentServiceImpl::UploadAttachments(attachment_ids); |
-} |
- |
-std::vector<syncer::AttachmentIdList>* |
-MockAttachmentService::attachment_id_lists() { |
- return &attachment_id_lists_; |
-} |
- |
-// MockSyncApiComponentFactory needed to initialize GenericChangeProcessor and |
-// pass MockAttachmentService to it. |
-class MockSyncApiComponentFactory : public SyncApiComponentFactory { |
- public: |
- MockSyncApiComponentFactory() {} |
- |
- // SyncApiComponentFactory implementation. |
- void RegisterDataTypes( |
- sync_driver::SyncService* sync_service, |
- const RegisterDataTypesMethod& register_platform_types_method) override {} |
- sync_driver::DataTypeManager* CreateDataTypeManager( |
- const syncer::WeakHandle<syncer::DataTypeDebugInfoListener>& |
- debug_info_listener, |
- const sync_driver::DataTypeController::TypeMap* controllers, |
- const sync_driver::DataTypeEncryptionHandler* encryption_handler, |
- browser_sync::SyncBackendHost* backend, |
- sync_driver::DataTypeManagerObserver* observer) override{ |
- return nullptr; |
- }; |
- browser_sync::SyncBackendHost* CreateSyncBackendHost( |
- const std::string& name, |
- invalidation::InvalidationService* invalidator, |
- const base::WeakPtr<sync_driver::SyncPrefs>& sync_prefs, |
- const base::FilePath& sync_folder) override { |
- return nullptr; |
- } |
- std::unique_ptr<sync_driver::LocalDeviceInfoProvider> |
- CreateLocalDeviceInfoProvider() override { |
- return nullptr; |
- } |
- SyncComponents CreateBookmarkSyncComponents( |
- sync_driver::SyncService* sync_service, |
- syncer::DataTypeErrorHandler* error_handler) override { |
- return SyncComponents(nullptr, nullptr); |
- } |
- |
- std::unique_ptr<syncer::AttachmentService> CreateAttachmentService( |
- std::unique_ptr<syncer::AttachmentStoreForSync> attachment_store, |
- const syncer::UserShare& user_share, |
- const std::string& store_birthday, |
- syncer::ModelType model_type, |
- syncer::AttachmentService::Delegate* delegate) override { |
- std::unique_ptr<MockAttachmentService> attachment_service( |
- new MockAttachmentService(std::move(attachment_store))); |
- // GenericChangeProcessor takes ownership of the AttachmentService, but we |
- // need to have a pointer to it so we can see that it was used properly. |
- // Take a pointer and trust that GenericChangeProcessor does not prematurely |
- // destroy it. |
- mock_attachment_service_ = attachment_service.get(); |
- return std::move(attachment_service); |
- } |
- |
- MockAttachmentService* GetMockAttachmentService() { |
- return mock_attachment_service_; |
- } |
- |
- private: |
- MockAttachmentService* mock_attachment_service_; |
-}; |
- |
-class SyncGenericChangeProcessorTest : public testing::Test { |
- public: |
- // Most test cases will use this type. For those that need a |
- // GenericChangeProcessor for a different type, use |InitializeForType|. |
- static const syncer::ModelType kType = syncer::PREFERENCES; |
- |
- SyncGenericChangeProcessorTest() |
- : syncable_service_ptr_factory_(&fake_syncable_service_), |
- mock_attachment_service_(NULL), |
- sync_client_(&sync_factory_) {} |
- |
- void SetUp() override { |
- // Use kType by default, but allow test cases to re-initialize with whatever |
- // type they choose. Therefore, it's important that all type dependent |
- // initialization occurs in InitializeForType. |
- InitializeForType(kType); |
- } |
- |
- void TearDown() override { |
- mock_attachment_service_ = NULL; |
- if (test_user_share_) { |
- test_user_share_->TearDown(); |
- } |
- } |
- |
- // Initialize GenericChangeProcessor and related classes for testing with |
- // model type |type|. |
- void InitializeForType(syncer::ModelType type) { |
- TearDown(); |
- test_user_share_.reset(new syncer::TestUserShare); |
- test_user_share_->SetUp(); |
- sync_merge_result_.reset(new syncer::SyncMergeResult(type)); |
- merge_result_ptr_factory_.reset( |
- new base::WeakPtrFactory<syncer::SyncMergeResult>( |
- sync_merge_result_.get())); |
- |
- syncer::ModelTypeSet types = syncer::ProtocolTypes(); |
- for (syncer::ModelTypeSet::Iterator iter = types.First(); iter.Good(); |
- iter.Inc()) { |
- syncer::TestUserShare::CreateRoot(iter.Get(), |
- test_user_share_->user_share()); |
- } |
- test_user_share_->encryption_handler()->Init(); |
- ConstructGenericChangeProcessor(type); |
- } |
- |
- void ConstructGenericChangeProcessor(syncer::ModelType type) { |
- std::unique_ptr<syncer::AttachmentStore> attachment_store = |
- syncer::AttachmentStore::CreateInMemoryStore(); |
- change_processor_.reset(new GenericChangeProcessor( |
- type, &data_type_error_handler_, |
- syncable_service_ptr_factory_.GetWeakPtr(), |
- merge_result_ptr_factory_->GetWeakPtr(), test_user_share_->user_share(), |
- &sync_client_, attachment_store->CreateAttachmentStoreForSync())); |
- mock_attachment_service_ = sync_factory_.GetMockAttachmentService(); |
- } |
- |
- void BuildChildNodes(syncer::ModelType type, int n) { |
- syncer::WriteTransaction trans(FROM_HERE, user_share()); |
- for (int i = 0; i < n; ++i) { |
- syncer::WriteNode node(&trans); |
- node.InitUniqueByCreation(type, base::StringPrintf("node%05d", i)); |
- } |
- } |
- |
- GenericChangeProcessor* change_processor() { |
- return change_processor_.get(); |
- } |
- |
- syncer::UserShare* user_share() { |
- return test_user_share_->user_share(); |
- } |
- |
- MockAttachmentService* mock_attachment_service() { |
- return mock_attachment_service_; |
- } |
- |
- void RunLoop() { |
- base::RunLoop run_loop; |
- run_loop.RunUntilIdle(); |
- } |
- |
- private: |
- base::MessageLoopForUI loop_; |
- |
- std::unique_ptr<syncer::SyncMergeResult> sync_merge_result_; |
- std::unique_ptr<base::WeakPtrFactory<syncer::SyncMergeResult>> |
- merge_result_ptr_factory_; |
- |
- syncer::FakeSyncableService fake_syncable_service_; |
- base::WeakPtrFactory<syncer::FakeSyncableService> |
- syncable_service_ptr_factory_; |
- |
- syncer::DataTypeErrorHandlerMock data_type_error_handler_; |
- std::unique_ptr<syncer::TestUserShare> test_user_share_; |
- MockAttachmentService* mock_attachment_service_; |
- FakeSyncClient sync_client_; |
- MockSyncApiComponentFactory sync_factory_; |
- |
- std::unique_ptr<GenericChangeProcessor> change_processor_; |
-}; |
- |
-// Similar to above, but focused on the method that implements sync/api |
-// interfaces and is hence exposed to datatypes directly. |
-TEST_F(SyncGenericChangeProcessorTest, StressGetAllSyncData) { |
- const int kNumChildNodes = 1000; |
- const int kRepeatCount = 1; |
- |
- ASSERT_NO_FATAL_FAILURE(BuildChildNodes(kType, kNumChildNodes)); |
- |
- for (int i = 0; i < kRepeatCount; ++i) { |
- syncer::SyncDataList sync_data = |
- change_processor()->GetAllSyncData(kType); |
- |
- // Start with a simple test. We can add more in-depth testing later. |
- EXPECT_EQ(static_cast<size_t>(kNumChildNodes), sync_data.size()); |
- } |
-} |
- |
-TEST_F(SyncGenericChangeProcessorTest, SetGetPasswords) { |
- InitializeForType(syncer::PASSWORDS); |
- const int kNumPasswords = 10; |
- sync_pb::PasswordSpecificsData password_data; |
- password_data.set_username_value("user"); |
- |
- sync_pb::EntitySpecifics password_holder; |
- |
- syncer::SyncChangeList change_list; |
- for (int i = 0; i < kNumPasswords; ++i) { |
- password_data.set_password_value( |
- base::StringPrintf("password%i", i)); |
- password_holder.mutable_password()->mutable_client_only_encrypted_data()-> |
- CopyFrom(password_data); |
- change_list.push_back( |
- syncer::SyncChange(FROM_HERE, |
- syncer::SyncChange::ACTION_ADD, |
- syncer::SyncData::CreateLocalData( |
- base::StringPrintf("tag%i", i), |
- base::StringPrintf("title%i", i), |
- password_holder))); |
- } |
- |
- ASSERT_FALSE( |
- change_processor()->ProcessSyncChanges(FROM_HERE, change_list).IsSet()); |
- |
- syncer::SyncDataList password_list( |
- change_processor()->GetAllSyncData(syncer::PASSWORDS)); |
- |
- ASSERT_EQ(password_list.size(), change_list.size()); |
- for (int i = 0; i < kNumPasswords; ++i) { |
- // Verify the password is returned properly. |
- ASSERT_TRUE(password_list[i].GetSpecifics().has_password()); |
- ASSERT_TRUE(password_list[i].GetSpecifics().password(). |
- has_client_only_encrypted_data()); |
- ASSERT_FALSE(password_list[i].GetSpecifics().password().has_encrypted()); |
- const sync_pb::PasswordSpecificsData& sync_password = |
- password_list[i].GetSpecifics().password().client_only_encrypted_data(); |
- const sync_pb::PasswordSpecificsData& change_password = |
- change_list[i].sync_data().GetSpecifics().password(). |
- client_only_encrypted_data(); |
- ASSERT_EQ(sync_password.password_value(), change_password.password_value()); |
- ASSERT_EQ(sync_password.username_value(), change_password.username_value()); |
- |
- // Verify the raw sync data was stored securely. |
- syncer::ReadTransaction read_transaction(FROM_HERE, user_share()); |
- syncer::ReadNode node(&read_transaction); |
- ASSERT_EQ(node.InitByClientTagLookup(syncer::PASSWORDS, |
- base::StringPrintf("tag%i", i)), |
- syncer::BaseNode::INIT_OK); |
- ASSERT_EQ(node.GetTitle(), "encrypted"); |
- const sync_pb::EntitySpecifics& raw_specifics = node.GetEntitySpecifics(); |
- ASSERT_TRUE(raw_specifics.has_password()); |
- ASSERT_TRUE(raw_specifics.password().has_encrypted()); |
- ASSERT_FALSE(raw_specifics.password().has_client_only_encrypted_data()); |
- } |
-} |
- |
-TEST_F(SyncGenericChangeProcessorTest, UpdatePasswords) { |
- InitializeForType(syncer::PASSWORDS); |
- const int kNumPasswords = 10; |
- sync_pb::PasswordSpecificsData password_data; |
- password_data.set_username_value("user"); |
- |
- sync_pb::EntitySpecifics password_holder; |
- |
- syncer::SyncChangeList change_list; |
- syncer::SyncChangeList change_list2; |
- for (int i = 0; i < kNumPasswords; ++i) { |
- password_data.set_password_value( |
- base::StringPrintf("password%i", i)); |
- password_holder.mutable_password()->mutable_client_only_encrypted_data()-> |
- CopyFrom(password_data); |
- change_list.push_back( |
- syncer::SyncChange(FROM_HERE, |
- syncer::SyncChange::ACTION_ADD, |
- syncer::SyncData::CreateLocalData( |
- base::StringPrintf("tag%i", i), |
- base::StringPrintf("title%i", i), |
- password_holder))); |
- password_data.set_password_value( |
- base::StringPrintf("password_m%i", i)); |
- password_holder.mutable_password()->mutable_client_only_encrypted_data()-> |
- CopyFrom(password_data); |
- change_list2.push_back( |
- syncer::SyncChange(FROM_HERE, |
- syncer::SyncChange::ACTION_UPDATE, |
- syncer::SyncData::CreateLocalData( |
- base::StringPrintf("tag%i", i), |
- base::StringPrintf("title_m%i", i), |
- password_holder))); |
- } |
- |
- ASSERT_FALSE( |
- change_processor()->ProcessSyncChanges(FROM_HERE, change_list).IsSet()); |
- ASSERT_FALSE( |
- change_processor()->ProcessSyncChanges(FROM_HERE, change_list2).IsSet()); |
- |
- syncer::SyncDataList password_list( |
- change_processor()->GetAllSyncData(syncer::PASSWORDS)); |
- |
- ASSERT_EQ(password_list.size(), change_list2.size()); |
- for (int i = 0; i < kNumPasswords; ++i) { |
- // Verify the password is returned properly. |
- ASSERT_TRUE(password_list[i].GetSpecifics().has_password()); |
- ASSERT_TRUE(password_list[i].GetSpecifics().password(). |
- has_client_only_encrypted_data()); |
- ASSERT_FALSE(password_list[i].GetSpecifics().password().has_encrypted()); |
- const sync_pb::PasswordSpecificsData& sync_password = |
- password_list[i].GetSpecifics().password().client_only_encrypted_data(); |
- const sync_pb::PasswordSpecificsData& change_password = |
- change_list2[i].sync_data().GetSpecifics().password(). |
- client_only_encrypted_data(); |
- ASSERT_EQ(sync_password.password_value(), change_password.password_value()); |
- ASSERT_EQ(sync_password.username_value(), change_password.username_value()); |
- |
- // Verify the raw sync data was stored securely. |
- syncer::ReadTransaction read_transaction(FROM_HERE, user_share()); |
- syncer::ReadNode node(&read_transaction); |
- ASSERT_EQ(node.InitByClientTagLookup(syncer::PASSWORDS, |
- base::StringPrintf("tag%i", i)), |
- syncer::BaseNode::INIT_OK); |
- ASSERT_EQ(node.GetTitle(), "encrypted"); |
- const sync_pb::EntitySpecifics& raw_specifics = node.GetEntitySpecifics(); |
- ASSERT_TRUE(raw_specifics.has_password()); |
- ASSERT_TRUE(raw_specifics.password().has_encrypted()); |
- ASSERT_FALSE(raw_specifics.password().has_client_only_encrypted_data()); |
- } |
-} |
- |
-// Verify that attachments on newly added or updated SyncData are passed to the |
-// AttachmentService. |
-TEST_F(SyncGenericChangeProcessorTest, |
- ProcessSyncChanges_AddUpdateWithAttachment) { |
- std::string tag = "client_tag"; |
- std::string title = "client_title"; |
- sync_pb::EntitySpecifics specifics; |
- sync_pb::PreferenceSpecifics* pref_specifics = specifics.mutable_preference(); |
- pref_specifics->set_name("test"); |
- |
- syncer::AttachmentIdList attachment_ids; |
- attachment_ids.push_back(syncer::AttachmentId::Create(0, 0)); |
- attachment_ids.push_back(syncer::AttachmentId::Create(0, 0)); |
- |
- // Add a SyncData with two attachments. |
- syncer::SyncChangeList change_list; |
- change_list.push_back( |
- syncer::SyncChange(FROM_HERE, |
- syncer::SyncChange::ACTION_ADD, |
- syncer::SyncData::CreateLocalDataWithAttachments( |
- tag, title, specifics, attachment_ids))); |
- ASSERT_FALSE( |
- change_processor()->ProcessSyncChanges(FROM_HERE, change_list).IsSet()); |
- RunLoop(); |
- |
- // Check that the AttachmentService received the new attachments. |
- ASSERT_EQ(mock_attachment_service()->attachment_id_lists()->size(), 1U); |
- const syncer::AttachmentIdList& attachments_added = |
- mock_attachment_service()->attachment_id_lists()->front(); |
- ASSERT_THAT( |
- attachments_added, |
- testing::UnorderedElementsAre(attachment_ids[0], attachment_ids[1])); |
- |
- // Update the SyncData, replacing its two attachments with one new attachment. |
- syncer::AttachmentIdList new_attachment_ids; |
- new_attachment_ids.push_back(syncer::AttachmentId::Create(0, 0)); |
- mock_attachment_service()->attachment_id_lists()->clear(); |
- change_list.clear(); |
- change_list.push_back( |
- syncer::SyncChange(FROM_HERE, |
- syncer::SyncChange::ACTION_UPDATE, |
- syncer::SyncData::CreateLocalDataWithAttachments( |
- tag, title, specifics, new_attachment_ids))); |
- ASSERT_FALSE( |
- change_processor()->ProcessSyncChanges(FROM_HERE, change_list).IsSet()); |
- RunLoop(); |
- |
- // Check that the AttachmentService received it. |
- ASSERT_EQ(mock_attachment_service()->attachment_id_lists()->size(), 1U); |
- const syncer::AttachmentIdList& new_attachments_added = |
- mock_attachment_service()->attachment_id_lists()->front(); |
- ASSERT_THAT(new_attachments_added, |
- testing::UnorderedElementsAre(new_attachment_ids[0])); |
-} |
- |
-// Verify that after attachment is uploaded GenericChangeProcessor updates |
-// corresponding entries |
-TEST_F(SyncGenericChangeProcessorTest, AttachmentUploaded) { |
- std::string tag = "client_tag"; |
- std::string title = "client_title"; |
- sync_pb::EntitySpecifics specifics; |
- sync_pb::PreferenceSpecifics* pref_specifics = specifics.mutable_preference(); |
- pref_specifics->set_name("test"); |
- |
- syncer::AttachmentIdList attachment_ids; |
- attachment_ids.push_back(syncer::AttachmentId::Create(0, 0)); |
- |
- // Add a SyncData with two attachments. |
- syncer::SyncChangeList change_list; |
- change_list.push_back( |
- syncer::SyncChange(FROM_HERE, |
- syncer::SyncChange::ACTION_ADD, |
- syncer::SyncData::CreateLocalDataWithAttachments( |
- tag, title, specifics, attachment_ids))); |
- ASSERT_FALSE( |
- change_processor()->ProcessSyncChanges(FROM_HERE, change_list).IsSet()); |
- |
- sync_pb::AttachmentIdProto attachment_id_proto = attachment_ids[0].GetProto(); |
- syncer::AttachmentId attachment_id = |
- syncer::AttachmentId::CreateFromProto(attachment_id_proto); |
- |
- change_processor()->OnAttachmentUploaded(attachment_id); |
- syncer::ReadTransaction read_transaction(FROM_HERE, user_share()); |
- syncer::ReadNode node(&read_transaction); |
- ASSERT_EQ(node.InitByClientTagLookup(kType, tag), syncer::BaseNode::INIT_OK); |
- attachment_ids = node.GetAttachmentIds(); |
- EXPECT_EQ(1U, attachment_ids.size()); |
-} |
- |
-// Verify that upon construction, all attachments not yet on the server are |
-// scheduled for upload. |
-TEST_F(SyncGenericChangeProcessorTest, UploadAllAttachmentsNotOnServer) { |
- // Create two attachment ids. id2 will be marked as "on server". |
- syncer::AttachmentId id1 = syncer::AttachmentId::Create(0, 0); |
- syncer::AttachmentId id2 = syncer::AttachmentId::Create(0, 0); |
- { |
- // Write an entry containing these two attachment ids. |
- syncer::WriteTransaction trans(FROM_HERE, user_share()); |
- syncer::ReadNode root(&trans); |
- ASSERT_EQ(syncer::BaseNode::INIT_OK, root.InitTypeRoot(kType)); |
- syncer::WriteNode node(&trans); |
- node.InitUniqueByCreation(kType, root, "some node"); |
- sync_pb::AttachmentMetadata metadata; |
- sync_pb::AttachmentMetadataRecord* record1 = metadata.add_record(); |
- *record1->mutable_id() = id1.GetProto(); |
- sync_pb::AttachmentMetadataRecord* record2 = metadata.add_record(); |
- *record2->mutable_id() = id2.GetProto(); |
- record2->set_is_on_server(true); |
- node.SetAttachmentMetadata(metadata); |
- } |
- |
- // Construct the GenericChangeProcessor and see that it asks the |
- // AttachmentService to upload id1 only. |
- ConstructGenericChangeProcessor(kType); |
- ASSERT_EQ(1U, mock_attachment_service()->attachment_id_lists()->size()); |
- ASSERT_THAT(mock_attachment_service()->attachment_id_lists()->front(), |
- testing::UnorderedElementsAre(id1)); |
-} |
- |
-// Test that attempting to add an entry that already exists still works. |
-TEST_F(SyncGenericChangeProcessorTest, AddExistingEntry) { |
- InitializeForType(syncer::SESSIONS); |
- sync_pb::EntitySpecifics sessions_specifics; |
- sessions_specifics.mutable_session()->set_session_tag("session tag"); |
- syncer::SyncChangeList changes; |
- |
- // First add it normally. |
- changes.push_back(syncer::SyncChange( |
- FROM_HERE, syncer::SyncChange::ACTION_ADD, |
- syncer::SyncData::CreateLocalData(base::StringPrintf("tag"), |
- base::StringPrintf("title"), |
- sessions_specifics))); |
- ASSERT_FALSE( |
- change_processor()->ProcessSyncChanges(FROM_HERE, changes).IsSet()); |
- |
- // Now attempt to add it again, but with different specifics. Should not |
- // result in an error and should still update the specifics. |
- sessions_specifics.mutable_session()->set_session_tag("session tag 2"); |
- changes[0] = |
- syncer::SyncChange(FROM_HERE, syncer::SyncChange::ACTION_ADD, |
- syncer::SyncData::CreateLocalData( |
- base::StringPrintf("tag"), |
- base::StringPrintf("title"), sessions_specifics)); |
- ASSERT_FALSE( |
- change_processor()->ProcessSyncChanges(FROM_HERE, changes).IsSet()); |
- |
- // Verify the data was updated properly. |
- syncer::SyncDataList sync_data = |
- change_processor()->GetAllSyncData(syncer::SESSIONS); |
- ASSERT_EQ(sync_data.size(), 1U); |
- ASSERT_EQ("session tag 2", |
- sync_data[0].GetSpecifics().session().session_tag()); |
- EXPECT_FALSE(syncer::SyncDataRemote(sync_data[0]).GetClientTagHash().empty()); |
-} |
- |
-} // namespace |
- |
-} // namespace sync_driver |