summaryrefslogtreecommitdiffstats
path: root/chrome
diff options
context:
space:
mode:
authoralbertb@google.com <albertb@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2010-02-22 22:49:00 +0000
committeralbertb@google.com <albertb@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2010-02-22 22:49:00 +0000
commit65b3aa1a9b6fcba6968c44079ae592448e2b99dc (patch)
tree0f139e70098dc9808029a64d78e50a2800139f8c /chrome
parent2670c482c99c1e91bdd0b05568bd32ae8a2e2ccf (diff)
downloadchromium_src-65b3aa1a9b6fcba6968c44079ae592448e2b99dc.zip
chromium_src-65b3aa1a9b6fcba6968c44079ae592448e2b99dc.tar.gz
chromium_src-65b3aa1a9b6fcba6968c44079ae592448e2b99dc.tar.bz2
Refactored parts of the PSS unit tests to allow for preference sync to be tested the same way bookmark sync is.
BUG=32409 TEST=Unit tests Review URL: http://codereview.chromium.org/614009 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@39649 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome')
-rw-r--r--chrome/browser/sync/glue/preference_change_processor.cc31
-rw-r--r--chrome/browser/sync/glue/preference_model_associator.cc12
-rw-r--r--chrome/browser/sync/glue/preference_model_associator.h2
-rw-r--r--chrome/browser/sync/glue/sync_backend_host.h1
-rw-r--r--chrome/browser/sync/profile_sync_service.h2
-rw-r--r--chrome/browser/sync/profile_sync_service_preference_unittest.cc172
-rw-r--r--chrome/browser/sync/profile_sync_service_unittest.cc93
-rw-r--r--chrome/browser/sync/profile_sync_test_util.h103
-rwxr-xr-xchrome/chrome_tests.gypi3
9 files changed, 310 insertions, 109 deletions
diff --git a/chrome/browser/sync/glue/preference_change_processor.cc b/chrome/browser/sync/glue/preference_change_processor.cc
index 772478e..6c79c9b 100644
--- a/chrome/browser/sync/glue/preference_change_processor.cc
+++ b/chrome/browser/sync/glue/preference_change_processor.cc
@@ -39,7 +39,7 @@ void PreferenceChangeProcessor::Observe(NotificationType type,
DCHECK(preference);
sync_api::WriteTransaction trans(share_handle());
- sync_api::WriteNode sync_node(&trans);
+ sync_api::WriteNode node(&trans);
int64 sync_id = model_associator_->GetSyncIdFromChromeId(*name);
if (sync_api::kInvalidId == sync_id) {
@@ -47,14 +47,14 @@ void PreferenceChangeProcessor::Observe(NotificationType type,
error_handler()->OnUnrecoverableError();
return;
} else {
- if (!sync_node.InitByIdLookup(sync_id)) {
+ if (!node.InitByIdLookup(sync_id)) {
LOG(ERROR) << "Preference node lookup failed.";
error_handler()->OnUnrecoverableError();
return;
}
}
- if (!WritePreference(&sync_node, WideToUTF8(*name),
+ if (!WritePreference(&node, WideToUTF8(*name),
preference->GetValue())) {
LOG(ERROR) << "Failed to update preference node.";
error_handler()->OnUnrecoverableError();
@@ -70,17 +70,8 @@ void PreferenceChangeProcessor::ApplyChangesFromSyncModel(
return;
StopObserving();
- // TODO(sync): Remove this once per-datatype filtering is working.
- sync_api::ReadNode root_node(trans);
- if (!root_node.InitByTagLookup(kPreferencesTag)) {
- LOG(ERROR) << "Preference root node lookup failed.";
- error_handler()->OnUnrecoverableError();
- return;
- }
-
- std::string name;
for (int i = 0; i < change_count; ++i) {
- sync_api::ReadNode sync_node(trans);
+ sync_api::ReadNode node(trans);
// TODO(ncarter): Can't look up the name for deletions: lookup of
// deleted items fails at the syncapi layer. However, the node should
// generally still exist in the syncable database; we just need to
@@ -92,22 +83,22 @@ void PreferenceChangeProcessor::ApplyChangesFromSyncModel(
continue;
}
- if (!sync_node.InitByIdLookup(changes[i].id)) {
+ if (!node.InitByIdLookup(changes[i].id)) {
LOG(ERROR) << "Preference node lookup failed.";
error_handler()->OnUnrecoverableError();
return;
}
+ DCHECK(syncable::PREFERENCES == node.GetModelType());
- // Check that the changed node is a child of the preferences folder.
- DCHECK(root_node.GetId() == sync_node.GetParentId());
- DCHECK(syncable::PREFERENCES == sync_node.GetModelType());
-
- scoped_ptr<Value> value(ReadPreference(&sync_node, &name));
+ std::string name;
+ scoped_ptr<Value> value(ReadPreference(&node, &name));
if (sync_api::SyncManager::ChangeRecord::ACTION_DELETE ==
changes[i].action) {
pref_service_->ClearPref(UTF8ToWide(name).c_str());
} else {
- if (value.get() && pref_service_->HasPrefPath(UTF8ToWide(name).c_str())) {
+ const PrefService::Preference* preference =
+ pref_service_->FindPreference(UTF8ToWide(name).c_str());
+ if (value.get() && preference) {
pref_service_->Set(UTF8ToWide(name).c_str(), *value);
}
}
diff --git a/chrome/browser/sync/glue/preference_model_associator.cc b/chrome/browser/sync/glue/preference_model_associator.cc
index 26cf8ed..dece295 100644
--- a/chrome/browser/sync/glue/preference_model_associator.cc
+++ b/chrome/browser/sync/glue/preference_model_associator.cc
@@ -34,11 +34,19 @@ bool PreferenceModelAssociator::AssociateModels() {
// TODO(albertb): Attempt to load the model association from storage.
PrefService* pref_service = sync_service_->profile()->GetPrefs();
+
+ int64 root_id;
+ if (!GetSyncIdForTaggedNode(kPreferencesTag, &root_id)) {
+ sync_service_->OnUnrecoverableError();
+ LOG(ERROR) << "Server did not create the top-level preferences node. We "
+ << "might be running against an out-of-date server.";
+ return false;
+ }
+
sync_api::WriteTransaction trans(
sync_service()->backend()->GetUserShareHandle());
-
sync_api::ReadNode root(&trans);
- if (!root.InitByTagLookup(kPreferencesTag)) {
+ if (!root.InitByIdLookup(root_id)) {
sync_service_->OnUnrecoverableError();
LOG(ERROR) << "Server did not create the top-level preferences node. We "
<< "might be running against an out-of-date server.";
diff --git a/chrome/browser/sync/glue/preference_model_associator.h b/chrome/browser/sync/glue/preference_model_associator.h
index 19551db..aa0669a 100644
--- a/chrome/browser/sync/glue/preference_model_associator.h
+++ b/chrome/browser/sync/glue/preference_model_associator.h
@@ -78,7 +78,7 @@ class PreferenceModelAssociator
// Returns whether a node with the given permanent tag was found and update
// |sync_id| with that node's id.
- bool GetSyncIdForTaggedNode(const std::string& tag, int64* sync_id);
+ virtual bool GetSyncIdForTaggedNode(const std::string& tag, int64* sync_id);
protected:
// Returns sync service instance.
diff --git a/chrome/browser/sync/glue/sync_backend_host.h b/chrome/browser/sync/glue/sync_backend_host.h
index 10d1534..5024f89 100644
--- a/chrome/browser/sync/glue/sync_backend_host.h
+++ b/chrome/browser/sync/glue/sync_backend_host.h
@@ -144,6 +144,7 @@ class SyncBackendHost : public browser_sync::ModelSafeWorkerRegistrar {
return;
registrar_.workers[GROUP_UI] = new UIModelWorker(frontend_loop_);
registrar_.routing_info[syncable::BOOKMARKS] = GROUP_PASSIVE;
+ registrar_.routing_info[syncable::PREFERENCES] = GROUP_PASSIVE;
core_thread_.message_loop()->PostTask(FROM_HERE,
NewRunnableMethod(core_.get(),
diff --git a/chrome/browser/sync/profile_sync_service.h b/chrome/browser/sync/profile_sync_service.h
index e1aa38d..ce36f98 100644
--- a/chrome/browser/sync/profile_sync_service.h
+++ b/chrome/browser/sync/profile_sync_service.h
@@ -257,8 +257,8 @@ class ProfileSyncService : public browser_sync::SyncFrontend,
private:
friend class ProfileSyncServiceTest;
+ friend class ProfileSyncServicePreferenceTest;
friend class ProfileSyncServiceTestHarness;
- friend class TestModelAssociator;
FRIEND_TEST(ProfileSyncServiceTest, UnrecoverableErrorSuspendsService);
// Initializes the various settings from the command line.
diff --git a/chrome/browser/sync/profile_sync_service_preference_unittest.cc b/chrome/browser/sync/profile_sync_service_preference_unittest.cc
new file mode 100644
index 0000000..a451988
--- /dev/null
+++ b/chrome/browser/sync/profile_sync_service_preference_unittest.cc
@@ -0,0 +1,172 @@
+// Copyright (c) 2010 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 "base/json/json_reader.h"
+#include "chrome/browser/sync/engine/syncapi.h"
+#include "chrome/browser/sync/glue/preference_change_processor.h"
+#include "chrome/browser/sync/glue/preference_data_type_controller.h"
+#include "chrome/browser/sync/glue/preference_model_associator.h"
+#include "chrome/browser/sync/glue/sync_backend_host.h"
+#include "chrome/browser/sync/profile_sync_test_util.h"
+#include "chrome/browser/sync/protocol/preference_specifics.pb.h"
+#include "chrome/browser/sync/test_profile_sync_service.h"
+#include "chrome/common/json_value_serializer.h"
+#include "chrome/common/pref_names.h"
+#include "chrome/test/testing_profile.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+using base::JSONReader;
+using browser_sync::PreferenceChangeProcessor;
+using browser_sync::PreferenceDataTypeController;
+using browser_sync::PreferenceModelAssociator;
+using browser_sync::SyncBackendHost;
+using sync_api::SyncManager;
+
+class TestPreferenceModelAssociator
+ : public TestModelAssociator<PreferenceModelAssociator> {
+ public:
+ TestPreferenceModelAssociator(ProfileSyncService* service)
+ : TestModelAssociator<PreferenceModelAssociator>(service) {
+ }
+};
+
+class ProfileSyncServicePreferenceTest : public testing::Test {
+ protected:
+ ProfileSyncServicePreferenceTest()
+ : ui_thread_(ChromeThread::UI, &message_loop_) {
+ }
+
+ virtual void SetUp() {
+ profile_.reset(new TestingProfile());
+ profile_->set_has_history_service(true);
+ }
+
+ virtual void TearDown() {
+ service_.reset();
+ profile_.reset();
+ MessageLoop::current()->RunAllPending();
+ }
+
+ void StartSyncService() {
+ if (!service_.get()) {
+ service_.reset(new TestProfileSyncService(profile_.get(), false));
+
+ // Register the preference data type.
+ model_associator_ = new TestPreferenceModelAssociator(service_.get());
+ change_processor_ = new PreferenceChangeProcessor(model_associator_,
+ service_.get());
+ factory_.reset(new TestProfileSyncFactory(NULL,
+ model_associator_,
+ change_processor_));
+
+ service_->RegisterDataTypeController(
+ new PreferenceDataTypeController(factory_.get(),
+ service_.get()));
+ service_->Initialize();
+ }
+ // The service may have already started sync automatically if it's already
+ // enabled by user once.
+ if (!service_->HasSyncSetupCompleted())
+ service_->EnableForUser();
+ }
+
+ SyncBackendHost* backend() { return service_->backend_.get(); }
+
+ const Value& GetPreferenceValue(const std::wstring& name) {
+ const PrefService::Preference* preference =
+ profile_->GetPrefs()->FindPreference(name.c_str());
+ return *preference->GetValue();
+ }
+
+ // Caller gets ownership of the returned value.
+ const Value* GetSyncedValue(const std::wstring& name) {
+ sync_api::ReadTransaction trans(backend()->GetUserShareHandle());
+ sync_api::ReadNode node(&trans);
+
+ int64 node_id = model_associator_->GetSyncIdFromChromeId(name);
+ EXPECT_NE(sync_api::kInvalidId, node_id);
+ EXPECT_TRUE(node.InitByIdLookup(node_id));
+
+ const sync_pb::PreferenceSpecifics& specifics(
+ node.GetPreferenceSpecifics());
+
+ JSONReader reader;
+ return reader.JsonToValue(specifics.value(), false, false);
+ }
+
+ // Caller gets ownership of the returned change record.
+ SyncManager::ChangeRecord* SetSyncedValue(const std::wstring& name,
+ const Value& value) {
+ sync_api::WriteTransaction trans(backend()->GetUserShareHandle());
+ sync_api::WriteNode node(&trans);
+
+ int64 node_id = model_associator_->GetSyncIdFromChromeId(name);
+ EXPECT_NE(sync_api::kInvalidId, node_id);
+ EXPECT_TRUE(node.InitByIdLookup(node_id));
+
+ std::string serialized;
+ JSONStringValueSerializer json(&serialized);
+ EXPECT_TRUE(json.Serialize(value));
+
+ sync_pb::PreferenceSpecifics preference;
+ preference.set_name(WideToUTF8(name));
+ preference.set_value(serialized);
+ node.SetPreferenceSpecifics(preference);
+
+ SyncManager::ChangeRecord* record = new SyncManager::ChangeRecord();
+ record->action = SyncManager::ChangeRecord::ACTION_UPDATE;
+ record->id = node_id;
+ return record;
+ }
+
+ scoped_ptr<TestProfileSyncService> service_;
+ scoped_ptr<TestingProfile> profile_;
+ scoped_ptr<TestProfileSyncFactory> factory_;
+
+ PreferenceModelAssociator* model_associator_;
+ PreferenceChangeProcessor* change_processor_;
+
+ MessageLoopForUI message_loop_;
+ ChromeThread ui_thread_;
+};
+
+TEST_F(ProfileSyncServicePreferenceTest, ModelAssociation) {
+ StartSyncService();
+ const std::set<std::wstring>& names = model_associator_->synced_preferences();
+ ASSERT_LT(0U, names.size());
+
+ for (std::set<std::wstring>::const_iterator it = names.begin();
+ it != names.end(); ++it) {
+ const Value& expected = GetPreferenceValue(*it);
+ scoped_ptr<const Value> actual(GetSyncedValue(*it));
+ EXPECT_TRUE(expected.Equals(actual.get())) << *it;
+ }
+}
+
+TEST_F(ProfileSyncServicePreferenceTest, UpdatedPreference) {
+ StartSyncService();
+
+ scoped_ptr<Value> expected(
+ Value::CreateStringValue("http://example.com/test/foo"));
+ profile_->GetPrefs()->Set(prefs::kHomePage, *expected);
+
+ scoped_ptr<const Value> actual(GetSyncedValue(prefs::kHomePage));
+ ASSERT_TRUE(expected->Equals(actual.get()));
+}
+
+TEST_F(ProfileSyncServicePreferenceTest, UpdatedSyncNode) {
+ StartSyncService();
+
+ scoped_ptr<Value> expected(
+ Value::CreateStringValue("http://example.com/test/bar"));
+ scoped_ptr<SyncManager::ChangeRecord> record(
+ SetSyncedValue(prefs::kHomePage, *expected));
+ {
+ sync_api::WriteTransaction trans(backend()->GetUserShareHandle());
+ change_processor_->ApplyChangesFromSyncModel(&trans, record.get(), 1);
+ }
+
+ const Value& actual = GetPreferenceValue(prefs::kHomePage);
+ ASSERT_TRUE(expected->Equals(&actual));
+}
diff --git a/chrome/browser/sync/profile_sync_service_unittest.cc b/chrome/browser/sync/profile_sync_service_unittest.cc
index ef71f1e..d3da5ed 100644
--- a/chrome/browser/sync/profile_sync_service_unittest.cc
+++ b/chrome/browser/sync/profile_sync_service_unittest.cc
@@ -23,6 +23,7 @@
#include "chrome/browser/sync/notification_method.h"
#include "chrome/browser/sync/profile_sync_factory.h"
#include "chrome/browser/sync/test_profile_sync_service.h"
+#include "chrome/browser/sync/profile_sync_test_util.h"
#include "chrome/common/chrome_switches.h"
#include "chrome/common/pref_names.h"
#include "chrome/test/testing_profile.h"
@@ -35,90 +36,12 @@ using browser_sync::ChangeProcessor;
using browser_sync::ModelAssociator;
using browser_sync::SyncBackendHost;
-class TestProfileSyncFactory : public ProfileSyncFactory {
+class TestBookmarkModelAssociator :
+ public TestModelAssociator<BookmarkModelAssociator> {
public:
- TestProfileSyncFactory(ProfileSyncService* profile_sync_service,
- AssociatorInterface* model_associator,
- ChangeProcessor* change_processor)
- : profile_sync_service_(profile_sync_service),
- model_associator_(model_associator),
- change_processor_(change_processor) {}
- virtual ~TestProfileSyncFactory() {}
-
- virtual ProfileSyncService* CreateProfileSyncService() {
- return profile_sync_service_.release();
+ explicit TestBookmarkModelAssociator(ProfileSyncService* service)
+ : TestModelAssociator<BookmarkModelAssociator>(service) {
}
-
- virtual SyncComponents CreateBookmarkSyncComponents(
- ProfileSyncService* service) {
- return SyncComponents(model_associator_.release(),
- change_processor_.release());
- }
-
- virtual SyncComponents CreatePreferenceSyncComponents(
- ProfileSyncService* service) {
- return SyncComponents(NULL, NULL);
- }
-
- private:
- scoped_ptr<ProfileSyncService> profile_sync_service_;
- scoped_ptr<AssociatorInterface> model_associator_;
- scoped_ptr<ChangeProcessor> change_processor_;
-
- DISALLOW_COPY_AND_ASSIGN(TestProfileSyncFactory);
-};
-
-class TestModelAssociator : public BookmarkModelAssociator {
- public:
- explicit TestModelAssociator(ProfileSyncService* service)
- : BookmarkModelAssociator(service) {
- }
-
- virtual bool GetSyncIdForTaggedNode(const std::string& tag, int64* sync_id) {
- std::wstring tag_wide;
- if (!UTF8ToWide(tag.c_str(), tag.length(), &tag_wide)) {
- NOTREACHED() << "Unable to convert UTF8 to wide for string: " << tag;
- return false;
- }
-
- sync_api::WriteTransaction trans(
- sync_service()->backend()->GetUserShareHandle());
- sync_api::ReadNode root(&trans);
- root.InitByRootLookup();
-
- // First, try to find a node with the title among the root's children.
- // This will be the case if we are testing model persistence, and
- // are reloading a sync repository created earlier in the test.
- int64 last_child_id = sync_api::kInvalidId;
- for (int64 id = root.GetFirstChildId(); id != sync_api::kInvalidId; /***/) {
- sync_api::ReadNode child(&trans);
- child.InitByIdLookup(id);
- last_child_id = id;
- if (tag_wide == child.GetTitle()) {
- *sync_id = id;
- return true;
- }
- id = child.GetSuccessorId();
- }
-
- sync_api::ReadNode predecessor_node(&trans);
- sync_api::ReadNode* predecessor = NULL;
- if (last_child_id != sync_api::kInvalidId) {
- predecessor_node.InitByIdLookup(last_child_id);
- predecessor = &predecessor_node;
- }
- sync_api::WriteNode node(&trans);
- // Create new fake tagged nodes at the end of the ordering.
- node.InitByCreation(syncable::BOOKMARKS, root, predecessor);
- node.SetIsFolder(true);
- node.SetTitle(tag_wide);
- node.SetExternalId(0);
- *sync_id = node.GetId();
- return true;
- }
-
- private:
- ~TestModelAssociator() {}
};
// FakeServerChange constructs a list of sync_api::ChangeRecords while modifying
@@ -302,7 +225,7 @@ class ProfileSyncServiceTest : public testing::Test {
service_.reset(new TestProfileSyncService(profile_.get(), false));
// Register the bookmark data type.
- model_associator_ = new TestModelAssociator(service_.get());
+ model_associator_ = new TestBookmarkModelAssociator(service_.get());
change_processor_ = new BookmarkChangeProcessor(model_associator_,
service_.get());
factory_.reset(new TestProfileSyncFactory(NULL,
@@ -493,7 +416,7 @@ class ProfileSyncServiceTest : public testing::Test {
scoped_ptr<TestingProfile> profile_;
scoped_ptr<TestProfileSyncFactory> factory_;
BookmarkModel* model_;
- TestModelAssociator* model_associator_;
+ TestBookmarkModelAssociator* model_associator_;
BookmarkChangeProcessor* change_processor_;
};
@@ -1376,7 +1299,7 @@ TEST_F(ProfileSyncServiceTestWithData, MAYBE_TestStartupWithOldSyncData) {
service_.reset(new TestProfileSyncService(profile_.get(), false));
profile_->GetPrefs()->SetBoolean(prefs::kSyncHasSetupCompleted, false);
- model_associator_ = new TestModelAssociator(service_.get());
+ model_associator_ = new TestBookmarkModelAssociator(service_.get());
change_processor_ = new BookmarkChangeProcessor(model_associator_,
service_.get());
factory_.reset(new TestProfileSyncFactory(NULL,
diff --git a/chrome/browser/sync/profile_sync_test_util.h b/chrome/browser/sync/profile_sync_test_util.h
new file mode 100644
index 0000000..48632fc
--- /dev/null
+++ b/chrome/browser/sync/profile_sync_test_util.h
@@ -0,0 +1,103 @@
+// Copyright (c) 2010 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.
+
+#ifndef CHROME_BROWSER_SYNC_PROFILE_SYNC_TEST_UTIL_H_
+#define CHROME_BROWSER_SYNC_PROFILE_SYNC_TEST_UTIL_H_
+
+#include "chrome/browser/sync/glue/bookmark_change_processor.h"
+#include "chrome/browser/sync/glue/bookmark_data_type_controller.h"
+#include "chrome/browser/sync/glue/bookmark_model_associator.h"
+#include "chrome/browser/sync/glue/change_processor.h"
+#include "chrome/browser/sync/profile_sync_factory.h"
+#include "chrome/browser/sync/profile_sync_service.h"
+#include "chrome/test/sync/test_http_bridge_factory.h"
+
+class TestProfileSyncFactory : public ProfileSyncFactory {
+ public:
+ TestProfileSyncFactory(ProfileSyncService* profile_sync_service,
+ browser_sync::AssociatorInterface* model_associator,
+ browser_sync::ChangeProcessor* change_processor)
+ : profile_sync_service_(profile_sync_service),
+ model_associator_(model_associator),
+ change_processor_(change_processor) {}
+ virtual ~TestProfileSyncFactory() {}
+
+ virtual ProfileSyncService* CreateProfileSyncService() {
+ return profile_sync_service_.release();
+ }
+
+ virtual SyncComponents CreateBookmarkSyncComponents(
+ ProfileSyncService* service) {
+ return SyncComponents(model_associator_.release(),
+ change_processor_.release());
+ }
+
+ virtual SyncComponents CreatePreferenceSyncComponents(
+ ProfileSyncService* service) {
+ return SyncComponents(model_associator_.release(),
+ change_processor_.release());
+ }
+
+ private:
+ scoped_ptr<ProfileSyncService> profile_sync_service_;
+ scoped_ptr<browser_sync::AssociatorInterface> model_associator_;
+ scoped_ptr<browser_sync::ChangeProcessor> change_processor_;
+
+ DISALLOW_COPY_AND_ASSIGN(TestProfileSyncFactory);
+};
+
+template <class ModelAssociatorImpl>
+class TestModelAssociator : public ModelAssociatorImpl {
+ public:
+ explicit TestModelAssociator(ProfileSyncService* service)
+ : ModelAssociatorImpl(service) {
+ }
+
+ virtual bool GetSyncIdForTaggedNode(const std::string& tag, int64* sync_id) {
+ std::wstring tag_wide;
+ if (!UTF8ToWide(tag.c_str(), tag.length(), &tag_wide)) {
+ NOTREACHED() << "Unable to convert UTF8 to wide for string: " << tag;
+ return false;
+ }
+
+ sync_api::WriteTransaction trans(
+ ModelAssociatorImpl::sync_service()->backend()->GetUserShareHandle());
+ sync_api::ReadNode root(&trans);
+ root.InitByRootLookup();
+
+ // First, try to find a node with the title among the root's children.
+ // This will be the case if we are testing model persistence, and
+ // are reloading a sync repository created earlier in the test.
+ int64 last_child_id = sync_api::kInvalidId;
+ for (int64 id = root.GetFirstChildId(); id != sync_api::kInvalidId; /***/) {
+ sync_api::ReadNode child(&trans);
+ child.InitByIdLookup(id);
+ last_child_id = id;
+ if (tag_wide == child.GetTitle()) {
+ *sync_id = id;
+ return true;
+ }
+ id = child.GetSuccessorId();
+ }
+
+ sync_api::ReadNode predecessor_node(&trans);
+ sync_api::ReadNode* predecessor = NULL;
+ if (last_child_id != sync_api::kInvalidId) {
+ predecessor_node.InitByIdLookup(last_child_id);
+ predecessor = &predecessor_node;
+ }
+ sync_api::WriteNode node(&trans);
+ // Create new fake tagged nodes at the end of the ordering.
+ node.InitByCreation(ModelAssociatorImpl::model_type(), root, predecessor);
+ node.SetIsFolder(true);
+ node.SetTitle(tag_wide);
+ node.SetExternalId(0);
+ *sync_id = node.GetId();
+ return true;
+ }
+
+ ~TestModelAssociator() {}
+};
+
+#endif // CHROME_BROWSER_SYNC_PROFILE_SYNC_TEST_UTIL_H_
diff --git a/chrome/chrome_tests.gypi b/chrome/chrome_tests.gypi
index 5bde6cf..d4744cf 100755
--- a/chrome/chrome_tests.gypi
+++ b/chrome/chrome_tests.gypi
@@ -481,6 +481,7 @@
'common',
'debugger',
'renderer',
+ 'sync_proto',
'syncapi',
'test_support_unit',
'utility',
@@ -826,6 +827,8 @@
'browser/sync/profile_sync_factory_impl_unittest.cc',
'browser/sync/profile_sync_factory_mock.cc',
'browser/sync/profile_sync_factory_mock.h',
+ 'browser/sync/profile_sync_service_preference_unittest.cc',
+ 'browser/sync/profile_sync_test_util.h',
'browser/sync/sync_setup_wizard_unittest.cc',
'browser/sync/sync_ui_util_mac_unittest.mm',
'browser/sync/test_profile_sync_service.h',