This source file includes following definitions.
- GetJson
- ValuesEq
- SettingsEq
- ProcessSyncChanges
- GetAllSyncData
- changes
- ClearChanges
- set_fail_all_requests
- GetOnlyChange
- GetExisting
- Create
- DeleteDatabaseIfExists
- sync_processor_wrapper_
- SetUp
- TearDown
- AddExtensionAndGetStorage
- GetSyncableService
- GetAllSyncData
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
#include "base/bind.h"
#include "base/files/scoped_temp_dir.h"
#include "base/json/json_reader.h"
#include "base/json/json_writer.h"
#include "base/memory/scoped_ptr.h"
#include "base/message_loop/message_loop.h"
#include "chrome/browser/extensions/api/storage/settings_sync_util.h"
#include "chrome/browser/extensions/api/storage/sync_value_store_cache.h"
#include "chrome/browser/extensions/api/storage/syncable_settings_storage.h"
#include "content/public/test/test_browser_thread.h"
#include "extensions/browser/api/storage/leveldb_settings_storage_factory.h"
#include "extensions/browser/api/storage/settings_storage_factory.h"
#include "extensions/browser/api/storage/settings_test_util.h"
#include "extensions/browser/api/storage/storage_frontend.h"
#include "extensions/browser/extension_system.h"
#include "extensions/browser/value_store/testing_value_store.h"
#include "extensions/common/manifest.h"
#include "sync/api/sync_change_processor.h"
#include "sync/api/sync_change_processor_wrapper_for_test.h"
#include "sync/api/sync_error_factory.h"
#include "sync/api/sync_error_factory_mock.h"
#include "testing/gtest/include/gtest/gtest.h"
using base::DictionaryValue;
using base::ListValue;
using base::Value;
using content::BrowserThread;
namespace extensions {
namespace util = settings_test_util;
namespace {
const ValueStore::WriteOptions DEFAULTS = ValueStore::DEFAULTS;
static std::string GetJson(const base::Value& value) {
std::string json;
base::JSONWriter::WriteWithOptions(&value,
base::JSONWriter::OPTIONS_PRETTY_PRINT,
&json);
return json;
}
testing::AssertionResult ValuesEq(
const char* _1, const char* _2,
const base::Value* expected,
const base::Value* actual) {
if (expected == actual) {
return testing::AssertionSuccess();
}
if (!expected && actual) {
return testing::AssertionFailure() <<
"Expected NULL, actual: " << GetJson(*actual);
}
if (expected && !actual) {
return testing::AssertionFailure() <<
"Expected: " << GetJson(*expected) << ", actual NULL";
}
if (!expected->Equals(actual)) {
return testing::AssertionFailure() <<
"Expected: " << GetJson(*expected) << ", actual: " << GetJson(*actual);
}
return testing::AssertionSuccess();
}
testing::AssertionResult SettingsEq(
const char* _1, const char* _2,
const base::DictionaryValue& expected,
ValueStore::ReadResult actual) {
if (actual->HasError()) {
return testing::AssertionFailure() <<
"Expected: " << expected <<
", actual has error: " << actual->error().message;
}
return ValuesEq(_1, _2, &expected, &actual->settings());
}
class MockSyncChangeProcessor : public syncer::SyncChangeProcessor {
public:
MockSyncChangeProcessor() : fail_all_requests_(false) {}
virtual syncer::SyncError ProcessSyncChanges(
const tracked_objects::Location& from_here,
const syncer::SyncChangeList& change_list) OVERRIDE {
if (fail_all_requests_) {
return syncer::SyncError(
FROM_HERE,
syncer::SyncError::DATATYPE_ERROR,
"MockSyncChangeProcessor: configured to fail",
change_list[0].sync_data().GetDataType());
}
for (syncer::SyncChangeList::const_iterator it = change_list.begin();
it != change_list.end(); ++it) {
changes_.push_back(SettingSyncData(*it));
}
return syncer::SyncError();
}
virtual syncer::SyncDataList GetAllSyncData(syncer::ModelType type) const
OVERRIDE {
return syncer::SyncDataList();
}
const SettingSyncDataList& changes() { return changes_; }
void ClearChanges() {
changes_.clear();
}
void set_fail_all_requests(bool fail_all_requests) {
fail_all_requests_ = fail_all_requests;
}
SettingSyncData GetOnlyChange(
const std::string& extension_id, const std::string& key) {
SettingSyncDataList matching_changes;
for (SettingSyncDataList::iterator it = changes_.begin();
it != changes_.end(); ++it) {
if (it->extension_id() == extension_id && it->key() == key) {
matching_changes.push_back(*it);
}
}
if (matching_changes.empty()) {
ADD_FAILURE() << "No matching changes for " << extension_id << "/" <<
key << " (out of " << changes_.size() << ")";
return SettingSyncData(syncer::SyncChange::ACTION_INVALID,
std::string(),
std::string(),
scoped_ptr<base::Value>(
new base::DictionaryValue()));
}
if (matching_changes.size() != 1u) {
ADD_FAILURE() << matching_changes.size() << " matching changes for " <<
extension_id << "/" << key << " (out of " << changes_.size() << ")";
}
return matching_changes[0];
}
private:
SettingSyncDataList changes_;
bool fail_all_requests_;
};
class TestingValueStoreFactory : public SettingsStorageFactory {
public:
TestingValueStore* GetExisting(const std::string& extension_id) {
DCHECK(created_.count(extension_id));
return created_[extension_id];
}
virtual ValueStore* Create(const base::FilePath& base_path,
const std::string& extension_id) OVERRIDE {
TestingValueStore* new_storage = new TestingValueStore();
DCHECK(!created_.count(extension_id));
created_[extension_id] = new_storage;
return new_storage;
}
virtual void DeleteDatabaseIfExists(
const base::FilePath& base_path,
const std::string& extension_id) OVERRIDE {}
private:
virtual ~TestingValueStoreFactory() {}
std::map<std::string, TestingValueStore*> created_;
};
}
class ExtensionSettingsSyncTest : public testing::Test {
public:
ExtensionSettingsSyncTest()
: ui_thread_(BrowserThread::UI, base::MessageLoop::current()),
file_thread_(BrowserThread::FILE, base::MessageLoop::current()),
storage_factory_(new util::ScopedSettingsStorageFactory()),
sync_processor_(new MockSyncChangeProcessor),
sync_processor_wrapper_(new syncer::SyncChangeProcessorWrapperForTest(
sync_processor_.get())) {}
virtual void SetUp() OVERRIDE {
ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
profile_.reset(new util::MockProfile(temp_dir_.path()));
storage_factory_->Reset(new LeveldbSettingsStorageFactory());
frontend_.reset(
StorageFrontend::CreateForTesting(storage_factory_, profile_.get()));
}
virtual void TearDown() OVERRIDE {
frontend_.reset();
profile_.reset();
message_loop_.RunUntilIdle();
}
protected:
ValueStore* AddExtensionAndGetStorage(
const std::string& id, Manifest::Type type) {
scoped_refptr<const Extension> extension =
util::AddExtensionWithId(profile_.get(), id, type);
return util::GetStorage(extension, frontend_.get());
}
syncer::SyncableService* GetSyncableService(syncer::ModelType model_type) {
base::MessageLoop::current()->RunUntilIdle();
SyncValueStoreCache* sync_cache = static_cast<SyncValueStoreCache*>(
frontend_->GetValueStoreCache(settings_namespace::SYNC));
return sync_cache->GetSyncableService(model_type);
}
std::map<std::string, SettingSyncDataList> GetAllSyncData(
syncer::ModelType model_type) {
syncer::SyncDataList as_list =
GetSyncableService(model_type)->GetAllSyncData(model_type);
std::map<std::string, SettingSyncDataList> as_map;
for (syncer::SyncDataList::iterator it = as_list.begin();
it != as_list.end(); ++it) {
SettingSyncData sync_data(*it);
as_map[sync_data.extension_id()].push_back(sync_data);
}
return as_map;
}
base::MessageLoop message_loop_;
content::TestBrowserThread ui_thread_;
content::TestBrowserThread file_thread_;
base::ScopedTempDir temp_dir_;
scoped_ptr<util::MockProfile> profile_;
scoped_ptr<StorageFrontend> frontend_;
scoped_refptr<util::ScopedSettingsStorageFactory> storage_factory_;
scoped_ptr<MockSyncChangeProcessor> sync_processor_;
scoped_ptr<syncer::SyncChangeProcessorWrapperForTest> sync_processor_wrapper_;
};
TEST_F(ExtensionSettingsSyncTest, NoDataDoesNotInvokeSync) {
syncer::ModelType model_type = syncer::EXTENSION_SETTINGS;
Manifest::Type type = Manifest::TYPE_EXTENSION;
EXPECT_EQ(0u, GetAllSyncData(model_type).size());
AddExtensionAndGetStorage("s1", type);
EXPECT_EQ(0u, GetAllSyncData(model_type).size());
GetSyncableService(model_type)->MergeDataAndStartSyncing(
model_type,
syncer::SyncDataList(),
sync_processor_wrapper_.PassAs<syncer::SyncChangeProcessor>(),
scoped_ptr<syncer::SyncErrorFactory>(new syncer::SyncErrorFactoryMock()));
AddExtensionAndGetStorage("s2", type);
EXPECT_EQ(0u, GetAllSyncData(model_type).size());
GetSyncableService(model_type)->StopSyncing(model_type);
EXPECT_EQ(0u, sync_processor_->changes().size());
EXPECT_EQ(0u, GetAllSyncData(model_type).size());
}
TEST_F(ExtensionSettingsSyncTest, InSyncDataDoesNotInvokeSync) {
syncer::ModelType model_type = syncer::APP_SETTINGS;
Manifest::Type type = Manifest::TYPE_LEGACY_PACKAGED_APP;
base::StringValue value1("fooValue");
base::ListValue value2;
value2.Append(new base::StringValue("barValue"));
ValueStore* storage1 = AddExtensionAndGetStorage("s1", type);
ValueStore* storage2 = AddExtensionAndGetStorage("s2", type);
storage1->Set(DEFAULTS, "foo", value1);
storage2->Set(DEFAULTS, "bar", value2);
std::map<std::string, SettingSyncDataList> all_sync_data =
GetAllSyncData(model_type);
EXPECT_EQ(2u, all_sync_data.size());
EXPECT_EQ(1u, all_sync_data["s1"].size());
EXPECT_PRED_FORMAT2(ValuesEq, &value1, &all_sync_data["s1"][0].value());
EXPECT_EQ(1u, all_sync_data["s2"].size());
EXPECT_PRED_FORMAT2(ValuesEq, &value2, &all_sync_data["s2"][0].value());
syncer::SyncDataList sync_data;
sync_data.push_back(settings_sync_util::CreateData(
"s1", "foo", value1, model_type));
sync_data.push_back(settings_sync_util::CreateData(
"s2", "bar", value2, model_type));
GetSyncableService(model_type)->MergeDataAndStartSyncing(
model_type,
sync_data,
sync_processor_wrapper_.PassAs<syncer::SyncChangeProcessor>(),
scoped_ptr<syncer::SyncErrorFactory>(new syncer::SyncErrorFactoryMock()));
EXPECT_EQ(0u, sync_processor_->changes().size());
storage1->Set(DEFAULTS, "foo", value1);
EXPECT_EQ(0u, sync_processor_->changes().size());
storage1->Set(DEFAULTS, "foo", value2);
EXPECT_EQ(1u, sync_processor_->changes().size());
SettingSyncData change = sync_processor_->GetOnlyChange("s1", "foo");
EXPECT_EQ(syncer::SyncChange::ACTION_UPDATE, change.change_type());
EXPECT_TRUE(value2.Equals(&change.value()));
GetSyncableService(model_type)->StopSyncing(model_type);
}
TEST_F(ExtensionSettingsSyncTest, LocalDataWithNoSyncDataIsPushedToSync) {
syncer::ModelType model_type = syncer::EXTENSION_SETTINGS;
Manifest::Type type = Manifest::TYPE_EXTENSION;
base::StringValue value1("fooValue");
base::ListValue value2;
value2.Append(new base::StringValue("barValue"));
ValueStore* storage1 = AddExtensionAndGetStorage("s1", type);
ValueStore* storage2 = AddExtensionAndGetStorage("s2", type);
storage1->Set(DEFAULTS, "foo", value1);
storage2->Set(DEFAULTS, "bar", value2);
GetSyncableService(model_type)->MergeDataAndStartSyncing(
model_type,
syncer::SyncDataList(),
sync_processor_wrapper_.PassAs<syncer::SyncChangeProcessor>(),
scoped_ptr<syncer::SyncErrorFactory>(new syncer::SyncErrorFactoryMock()));
EXPECT_EQ(2u, sync_processor_->changes().size());
SettingSyncData change = sync_processor_->GetOnlyChange("s1", "foo");
EXPECT_EQ(syncer::SyncChange::ACTION_ADD, change.change_type());
EXPECT_TRUE(value1.Equals(&change.value()));
change = sync_processor_->GetOnlyChange("s2", "bar");
EXPECT_EQ(syncer::SyncChange::ACTION_ADD, change.change_type());
EXPECT_TRUE(value2.Equals(&change.value()));
GetSyncableService(model_type)->StopSyncing(model_type);
}
TEST_F(ExtensionSettingsSyncTest, AnySyncDataOverwritesLocalData) {
syncer::ModelType model_type = syncer::APP_SETTINGS;
Manifest::Type type = Manifest::TYPE_LEGACY_PACKAGED_APP;
base::StringValue value1("fooValue");
base::ListValue value2;
value2.Append(new base::StringValue("barValue"));
base::DictionaryValue expected1, expected2;
ValueStore* storage1 = AddExtensionAndGetStorage("s1", type);
storage1->Set(DEFAULTS, "overwriteMe", value1);
syncer::SyncDataList sync_data;
sync_data.push_back(settings_sync_util::CreateData(
"s1", "foo", value1, model_type));
sync_data.push_back(settings_sync_util::CreateData(
"s2", "bar", value2, model_type));
GetSyncableService(model_type)->MergeDataAndStartSyncing(
model_type,
sync_data,
sync_processor_wrapper_.PassAs<syncer::SyncChangeProcessor>(),
scoped_ptr<syncer::SyncErrorFactory>(new syncer::SyncErrorFactoryMock()));
expected1.Set("foo", value1.DeepCopy());
expected2.Set("bar", value2.DeepCopy());
ValueStore* storage2 = AddExtensionAndGetStorage("s2", type);
EXPECT_EQ(0u, sync_processor_->changes().size());
EXPECT_PRED_FORMAT2(SettingsEq, expected1, storage1->Get());
EXPECT_PRED_FORMAT2(SettingsEq, expected2, storage2->Get());
GetSyncableService(model_type)->StopSyncing(model_type);
}
TEST_F(ExtensionSettingsSyncTest, ProcessSyncChanges) {
syncer::ModelType model_type = syncer::EXTENSION_SETTINGS;
Manifest::Type type = Manifest::TYPE_EXTENSION;
base::StringValue value1("fooValue");
base::ListValue value2;
value2.Append(new base::StringValue("barValue"));
base::DictionaryValue expected1, expected2;
ValueStore* storage1 = AddExtensionAndGetStorage("s1", type);
ValueStore* storage2 = AddExtensionAndGetStorage("s2", type);
storage1->Set(DEFAULTS, "foo", value1);
expected1.Set("foo", value1.DeepCopy());
syncer::SyncDataList sync_data;
sync_data.push_back(settings_sync_util::CreateData(
"s2", "bar", value2, model_type));
GetSyncableService(model_type)->MergeDataAndStartSyncing(
model_type,
sync_data,
sync_processor_wrapper_.PassAs<syncer::SyncChangeProcessor>(),
scoped_ptr<syncer::SyncErrorFactory>(new syncer::SyncErrorFactoryMock()));
expected2.Set("bar", value2.DeepCopy());
syncer::SyncChangeList change_list;
change_list.push_back(settings_sync_util::CreateAdd(
"s1", "bar", value2, model_type));
change_list.push_back(settings_sync_util::CreateAdd(
"s2", "foo", value1, model_type));
GetSyncableService(model_type)->ProcessSyncChanges(FROM_HERE, change_list);
expected1.Set("bar", value2.DeepCopy());
expected2.Set("foo", value1.DeepCopy());
EXPECT_PRED_FORMAT2(SettingsEq, expected1, storage1->Get());
EXPECT_PRED_FORMAT2(SettingsEq, expected2, storage2->Get());
change_list.clear();
change_list.push_back(settings_sync_util::CreateUpdate(
"s1", "bar", value2, model_type));
change_list.push_back(settings_sync_util::CreateUpdate(
"s2", "bar", value1, model_type));
GetSyncableService(model_type)->ProcessSyncChanges(FROM_HERE, change_list);
expected1.Set("bar", value2.DeepCopy());
expected2.Set("bar", value1.DeepCopy());
EXPECT_PRED_FORMAT2(SettingsEq, expected1, storage1->Get());
EXPECT_PRED_FORMAT2(SettingsEq, expected2, storage2->Get());
change_list.clear();
change_list.push_back(settings_sync_util::CreateDelete(
"s1", "foo", model_type));
change_list.push_back(settings_sync_util::CreateDelete(
"s2", "foo", model_type));
GetSyncableService(model_type)->ProcessSyncChanges(FROM_HERE, change_list);
expected1.Remove("foo", NULL);
expected2.Remove("foo", NULL);
EXPECT_PRED_FORMAT2(SettingsEq, expected1, storage1->Get());
EXPECT_PRED_FORMAT2(SettingsEq, expected2, storage2->Get());
GetSyncableService(model_type)->StopSyncing(model_type);
}
TEST_F(ExtensionSettingsSyncTest, PushToSync) {
syncer::ModelType model_type = syncer::APP_SETTINGS;
Manifest::Type type = Manifest::TYPE_LEGACY_PACKAGED_APP;
base::StringValue value1("fooValue");
base::ListValue value2;
value2.Append(new base::StringValue("barValue"));
ValueStore* storage1 = AddExtensionAndGetStorage("s1", type);
ValueStore* storage2 = AddExtensionAndGetStorage("s2", type);
ValueStore* storage3 = AddExtensionAndGetStorage("s3", type);
ValueStore* storage4 = AddExtensionAndGetStorage("s4", type);
storage1->Set(DEFAULTS, "foo", value1);
storage2->Set(DEFAULTS, "foo", value1);
syncer::SyncDataList sync_data;
sync_data.push_back(settings_sync_util::CreateData(
"s3", "bar", value2, model_type));
sync_data.push_back(settings_sync_util::CreateData(
"s4", "bar", value2, model_type));
GetSyncableService(model_type)->MergeDataAndStartSyncing(
model_type,
sync_data,
sync_processor_wrapper_.PassAs<syncer::SyncChangeProcessor>(),
scoped_ptr<syncer::SyncErrorFactory>(new syncer::SyncErrorFactoryMock()));
storage1->Set(DEFAULTS, "bar", value2);
storage2->Set(DEFAULTS, "bar", value2);
storage3->Set(DEFAULTS, "foo", value1);
storage4->Set(DEFAULTS, "foo", value1);
SettingSyncData change = sync_processor_->GetOnlyChange("s1", "bar");
EXPECT_EQ(syncer::SyncChange::ACTION_ADD, change.change_type());
EXPECT_TRUE(value2.Equals(&change.value()));
sync_processor_->GetOnlyChange("s2", "bar");
EXPECT_EQ(syncer::SyncChange::ACTION_ADD, change.change_type());
EXPECT_TRUE(value2.Equals(&change.value()));
change = sync_processor_->GetOnlyChange("s3", "foo");
EXPECT_EQ(syncer::SyncChange::ACTION_ADD, change.change_type());
EXPECT_TRUE(value1.Equals(&change.value()));
change = sync_processor_->GetOnlyChange("s4", "foo");
EXPECT_EQ(syncer::SyncChange::ACTION_ADD, change.change_type());
EXPECT_TRUE(value1.Equals(&change.value()));
sync_processor_->ClearChanges();
storage1->Set(DEFAULTS, "bar", value1);
storage2->Set(DEFAULTS, "foo", value2);
storage3->Set(DEFAULTS, "bar", value1);
storage4->Set(DEFAULTS, "foo", value2);
change = sync_processor_->GetOnlyChange("s1", "bar");
EXPECT_EQ(syncer::SyncChange::ACTION_UPDATE, change.change_type());
EXPECT_TRUE(value1.Equals(&change.value()));
change = sync_processor_->GetOnlyChange("s2", "foo");
EXPECT_EQ(syncer::SyncChange::ACTION_UPDATE, change.change_type());
EXPECT_TRUE(value2.Equals(&change.value()));
change = sync_processor_->GetOnlyChange("s3", "bar");
EXPECT_EQ(syncer::SyncChange::ACTION_UPDATE, change.change_type());
EXPECT_TRUE(value1.Equals(&change.value()));
change = sync_processor_->GetOnlyChange("s4", "foo");
EXPECT_EQ(syncer::SyncChange::ACTION_UPDATE, change.change_type());
EXPECT_TRUE(value2.Equals(&change.value()));
sync_processor_->ClearChanges();
storage1->Remove("foo");
storage2->Remove("bar");
storage3->Remove("foo");
storage4->Remove("bar");
EXPECT_EQ(
syncer::SyncChange::ACTION_DELETE,
sync_processor_->GetOnlyChange("s1", "foo").change_type());
EXPECT_EQ(
syncer::SyncChange::ACTION_DELETE,
sync_processor_->GetOnlyChange("s2", "bar").change_type());
EXPECT_EQ(
syncer::SyncChange::ACTION_DELETE,
sync_processor_->GetOnlyChange("s3", "foo").change_type());
EXPECT_EQ(
syncer::SyncChange::ACTION_DELETE,
sync_processor_->GetOnlyChange("s4", "bar").change_type());
sync_processor_->ClearChanges();
storage1->Remove("foo");
storage2->Remove("bar");
storage3->Remove("foo");
storage4->Remove("bar");
EXPECT_EQ(0u, sync_processor_->changes().size());
storage1->Set(DEFAULTS, "foo", value1);
storage2->Set(DEFAULTS, "bar", value2);
storage3->Set(DEFAULTS, "foo", value1);
storage4->Set(DEFAULTS, "bar", value2);
sync_processor_->ClearChanges();
storage1->Clear();
storage2->Clear();
storage3->Clear();
storage4->Clear();
EXPECT_EQ(
syncer::SyncChange::ACTION_DELETE,
sync_processor_->GetOnlyChange("s1", "foo").change_type());
EXPECT_EQ(
syncer::SyncChange::ACTION_DELETE,
sync_processor_->GetOnlyChange("s1", "bar").change_type());
EXPECT_EQ(
syncer::SyncChange::ACTION_DELETE,
sync_processor_->GetOnlyChange("s2", "foo").change_type());
EXPECT_EQ(
syncer::SyncChange::ACTION_DELETE,
sync_processor_->GetOnlyChange("s2", "bar").change_type());
EXPECT_EQ(
syncer::SyncChange::ACTION_DELETE,
sync_processor_->GetOnlyChange("s3", "foo").change_type());
EXPECT_EQ(
syncer::SyncChange::ACTION_DELETE,
sync_processor_->GetOnlyChange("s3", "bar").change_type());
EXPECT_EQ(
syncer::SyncChange::ACTION_DELETE,
sync_processor_->GetOnlyChange("s4", "foo").change_type());
EXPECT_EQ(
syncer::SyncChange::ACTION_DELETE,
sync_processor_->GetOnlyChange("s4", "bar").change_type());
GetSyncableService(model_type)->StopSyncing(model_type);
}
TEST_F(ExtensionSettingsSyncTest, ExtensionAndAppSettingsSyncSeparately) {
base::StringValue value1("fooValue");
base::ListValue value2;
value2.Append(new base::StringValue("barValue"));
ValueStore* storage1 = AddExtensionAndGetStorage(
"s1", Manifest::TYPE_EXTENSION);
ValueStore* storage2 = AddExtensionAndGetStorage(
"s2", Manifest::TYPE_LEGACY_PACKAGED_APP);
storage1->Set(DEFAULTS, "foo", value1);
storage2->Set(DEFAULTS, "bar", value2);
std::map<std::string, SettingSyncDataList> extension_sync_data =
GetAllSyncData(syncer::EXTENSION_SETTINGS);
EXPECT_EQ(1u, extension_sync_data.size());
EXPECT_EQ(1u, extension_sync_data["s1"].size());
EXPECT_PRED_FORMAT2(ValuesEq, &value1, &extension_sync_data["s1"][0].value());
std::map<std::string, SettingSyncDataList> app_sync_data =
GetAllSyncData(syncer::APP_SETTINGS);
EXPECT_EQ(1u, app_sync_data.size());
EXPECT_EQ(1u, app_sync_data["s2"].size());
EXPECT_PRED_FORMAT2(ValuesEq, &value2, &app_sync_data["s2"][0].value());
syncer::SyncDataList sync_data;
sync_data.push_back(settings_sync_util::CreateData(
"s1", "foo", value1, syncer::EXTENSION_SETTINGS));
GetSyncableService(syncer::EXTENSION_SETTINGS)->MergeDataAndStartSyncing(
syncer::EXTENSION_SETTINGS,
sync_data,
sync_processor_wrapper_.PassAs<syncer::SyncChangeProcessor>(),
scoped_ptr<syncer::SyncErrorFactory>(new syncer::SyncErrorFactoryMock()));
GetSyncableService(syncer::EXTENSION_SETTINGS)->
StopSyncing(syncer::EXTENSION_SETTINGS);
EXPECT_EQ(0u, sync_processor_->changes().size());
sync_data.clear();
sync_data.push_back(settings_sync_util::CreateData(
"s2", "bar", value2, syncer::APP_SETTINGS));
scoped_ptr<syncer::SyncChangeProcessorWrapperForTest> app_settings_delegate_(
new syncer::SyncChangeProcessorWrapperForTest(sync_processor_.get()));
GetSyncableService(syncer::APP_SETTINGS)->MergeDataAndStartSyncing(
syncer::APP_SETTINGS,
sync_data,
app_settings_delegate_.PassAs<syncer::SyncChangeProcessor>(),
scoped_ptr<syncer::SyncErrorFactory>(new syncer::SyncErrorFactoryMock()));
GetSyncableService(syncer::APP_SETTINGS)->
StopSyncing(syncer::APP_SETTINGS);
EXPECT_EQ(0u, sync_processor_->changes().size());
}
TEST_F(ExtensionSettingsSyncTest, FailingStartSyncingDisablesSync) {
syncer::ModelType model_type = syncer::EXTENSION_SETTINGS;
Manifest::Type type = Manifest::TYPE_EXTENSION;
base::StringValue fooValue("fooValue");
base::StringValue barValue("barValue");
TestingValueStoreFactory* testing_factory = new TestingValueStoreFactory();
storage_factory_->Reset(testing_factory);
ValueStore* good = AddExtensionAndGetStorage("good", type);
ValueStore* bad = AddExtensionAndGetStorage("bad", type);
testing_factory->GetExisting("bad")->set_error_code(ValueStore::CORRUPTION);
{
syncer::SyncDataList sync_data;
sync_data.push_back(settings_sync_util::CreateData(
"good", "foo", fooValue, model_type));
sync_data.push_back(settings_sync_util::CreateData(
"bad", "foo", fooValue, model_type));
GetSyncableService(model_type)->MergeDataAndStartSyncing(
model_type,
sync_data,
sync_processor_wrapper_.PassAs<syncer::SyncChangeProcessor>(),
scoped_ptr<syncer::SyncErrorFactory>(
new syncer::SyncErrorFactoryMock()));
}
testing_factory->GetExisting("bad")->set_error_code(ValueStore::OK);
{
base::DictionaryValue dict;
dict.Set("foo", fooValue.DeepCopy());
EXPECT_PRED_FORMAT2(SettingsEq, dict, good->Get());
}
{
base::DictionaryValue dict;
EXPECT_PRED_FORMAT2(SettingsEq, dict, bad->Get());
}
sync_processor_->ClearChanges();
good->Set(DEFAULTS, "bar", barValue);
bad->Set(DEFAULTS, "bar", barValue);
EXPECT_EQ(
syncer::SyncChange::ACTION_ADD,
sync_processor_->GetOnlyChange("good", "bar").change_type());
EXPECT_EQ(1u, sync_processor_->changes().size());
{
base::DictionaryValue dict;
dict.Set("foo", fooValue.DeepCopy());
dict.Set("bar", barValue.DeepCopy());
EXPECT_PRED_FORMAT2(SettingsEq, dict, good->Get());
}
{
base::DictionaryValue dict;
dict.Set("bar", barValue.DeepCopy());
EXPECT_PRED_FORMAT2(SettingsEq, dict, bad->Get());
}
{
syncer::SyncChangeList change_list;
change_list.push_back(settings_sync_util::CreateUpdate(
"good", "foo", barValue, model_type));
change_list.push_back(settings_sync_util::CreateUpdate(
"bad", "foo", barValue, model_type));
GetSyncableService(model_type)->ProcessSyncChanges(FROM_HERE, change_list);
}
{
base::DictionaryValue dict;
dict.Set("foo", barValue.DeepCopy());
dict.Set("bar", barValue.DeepCopy());
EXPECT_PRED_FORMAT2(SettingsEq, dict, good->Get());
}
{
base::DictionaryValue dict;
dict.Set("bar", barValue.DeepCopy());
EXPECT_PRED_FORMAT2(SettingsEq, dict, bad->Get());
}
sync_processor_->ClearChanges();
good->Set(DEFAULTS, "bar", fooValue);
bad->Set(DEFAULTS, "bar", fooValue);
EXPECT_EQ(
syncer::SyncChange::ACTION_UPDATE,
sync_processor_->GetOnlyChange("good", "bar").change_type());
EXPECT_EQ(1u, sync_processor_->changes().size());
{
base::DictionaryValue dict;
dict.Set("foo", barValue.DeepCopy());
dict.Set("bar", fooValue.DeepCopy());
EXPECT_PRED_FORMAT2(SettingsEq, dict, good->Get());
}
{
base::DictionaryValue dict;
dict.Set("bar", fooValue.DeepCopy());
EXPECT_PRED_FORMAT2(SettingsEq, dict, bad->Get());
}
testing_factory->GetExisting("bad")->set_error_code(ValueStore::CORRUPTION);
{
syncer::SyncChangeList change_list;
change_list.push_back(settings_sync_util::CreateUpdate(
"good", "foo", fooValue, model_type));
change_list.push_back(settings_sync_util::CreateUpdate(
"bad", "foo", fooValue, model_type));
GetSyncableService(model_type)->ProcessSyncChanges(FROM_HERE, change_list);
}
testing_factory->GetExisting("bad")->set_error_code(ValueStore::OK);
{
base::DictionaryValue dict;
dict.Set("foo", fooValue.DeepCopy());
dict.Set("bar", fooValue.DeepCopy());
EXPECT_PRED_FORMAT2(SettingsEq, dict, good->Get());
}
{
base::DictionaryValue dict;
dict.Set("bar", fooValue.DeepCopy());
EXPECT_PRED_FORMAT2(SettingsEq, dict, bad->Get());
}
sync_processor_->ClearChanges();
GetSyncableService(model_type)->StopSyncing(model_type);
sync_processor_wrapper_.reset(
new syncer::SyncChangeProcessorWrapperForTest(sync_processor_.get()));
GetSyncableService(model_type)->MergeDataAndStartSyncing(
model_type,
syncer::SyncDataList(),
sync_processor_wrapper_.PassAs<syncer::SyncChangeProcessor>(),
scoped_ptr<syncer::SyncErrorFactory>(new syncer::SyncErrorFactoryMock()));
EXPECT_EQ(
syncer::SyncChange::ACTION_ADD,
sync_processor_->GetOnlyChange("good", "foo").change_type());
EXPECT_EQ(
syncer::SyncChange::ACTION_ADD,
sync_processor_->GetOnlyChange("good", "bar").change_type());
EXPECT_EQ(
syncer::SyncChange::ACTION_ADD,
sync_processor_->GetOnlyChange("bad", "bar").change_type());
EXPECT_EQ(3u, sync_processor_->changes().size());
sync_processor_->ClearChanges();
good->Set(DEFAULTS, "bar", barValue);
bad->Set(DEFAULTS, "bar", barValue);
EXPECT_EQ(
syncer::SyncChange::ACTION_UPDATE,
sync_processor_->GetOnlyChange("good", "bar").change_type());
EXPECT_EQ(
syncer::SyncChange::ACTION_UPDATE,
sync_processor_->GetOnlyChange("bad", "bar").change_type());
EXPECT_EQ(2u, sync_processor_->changes().size());
{
syncer::SyncChangeList change_list;
change_list.push_back(settings_sync_util::CreateUpdate(
"good", "bar", fooValue, model_type));
change_list.push_back(settings_sync_util::CreateUpdate(
"bad", "bar", fooValue, model_type));
GetSyncableService(model_type)->ProcessSyncChanges(FROM_HERE, change_list);
}
{
base::DictionaryValue dict;
dict.Set("foo", fooValue.DeepCopy());
dict.Set("bar", fooValue.DeepCopy());
EXPECT_PRED_FORMAT2(SettingsEq, dict, good->Get());
}
{
base::DictionaryValue dict;
dict.Set("bar", fooValue.DeepCopy());
EXPECT_PRED_FORMAT2(SettingsEq, dict, bad->Get());
}
}
TEST_F(ExtensionSettingsSyncTest, FailingProcessChangesDisablesSync) {
syncer::ModelType model_type = syncer::APP_SETTINGS;
Manifest::Type type = Manifest::TYPE_LEGACY_PACKAGED_APP;
base::StringValue fooValue("fooValue");
base::StringValue barValue("barValue");
TestingValueStoreFactory* testing_factory = new TestingValueStoreFactory();
storage_factory_->Reset(testing_factory);
ValueStore* good = AddExtensionAndGetStorage("good", type);
ValueStore* bad = AddExtensionAndGetStorage("bad", type);
{
syncer::SyncDataList sync_data;
sync_data.push_back(settings_sync_util::CreateData(
"good", "foo", fooValue, model_type));
sync_data.push_back(settings_sync_util::CreateData(
"bad", "foo", fooValue, model_type));
GetSyncableService(model_type)->MergeDataAndStartSyncing(
model_type,
sync_data,
sync_processor_wrapper_.PassAs<syncer::SyncChangeProcessor>(),
scoped_ptr<syncer::SyncErrorFactory>(
new syncer::SyncErrorFactoryMock()));
}
EXPECT_EQ(0u, sync_processor_->changes().size());
{
base::DictionaryValue dict;
dict.Set("foo", fooValue.DeepCopy());
EXPECT_PRED_FORMAT2(SettingsEq, dict, good->Get());
}
{
base::DictionaryValue dict;
dict.Set("foo", fooValue.DeepCopy());
EXPECT_PRED_FORMAT2(SettingsEq, dict, bad->Get());
}
testing_factory->GetExisting("bad")->set_error_code(ValueStore::CORRUPTION);
{
syncer::SyncChangeList change_list;
change_list.push_back(settings_sync_util::CreateAdd(
"good", "bar", barValue, model_type));
change_list.push_back(settings_sync_util::CreateAdd(
"bad", "bar", barValue, model_type));
GetSyncableService(model_type)->ProcessSyncChanges(FROM_HERE, change_list);
}
testing_factory->GetExisting("bad")->set_error_code(ValueStore::OK);
{
base::DictionaryValue dict;
dict.Set("foo", fooValue.DeepCopy());
dict.Set("bar", barValue.DeepCopy());
EXPECT_PRED_FORMAT2(SettingsEq, dict, good->Get());
}
{
base::DictionaryValue dict;
dict.Set("foo", fooValue.DeepCopy());
EXPECT_PRED_FORMAT2(SettingsEq, dict, bad->Get());
}
sync_processor_->ClearChanges();
good->Set(DEFAULTS, "foo", barValue);
bad->Set(DEFAULTS, "foo", barValue);
EXPECT_EQ(
syncer::SyncChange::ACTION_UPDATE,
sync_processor_->GetOnlyChange("good", "foo").change_type());
EXPECT_EQ(1u, sync_processor_->changes().size());
{
syncer::SyncChangeList change_list;
change_list.push_back(settings_sync_util::CreateAdd(
"good", "foo", fooValue, model_type));
change_list.push_back(settings_sync_util::CreateAdd(
"bad", "foo", fooValue, model_type));
GetSyncableService(model_type)->ProcessSyncChanges(FROM_HERE, change_list);
}
{
base::DictionaryValue dict;
dict.Set("foo", fooValue.DeepCopy());
dict.Set("bar", barValue.DeepCopy());
EXPECT_PRED_FORMAT2(SettingsEq, dict, good->Get());
}
{
base::DictionaryValue dict;
dict.Set("foo", barValue.DeepCopy());
EXPECT_PRED_FORMAT2(SettingsEq, dict, bad->Get());
}
}
TEST_F(ExtensionSettingsSyncTest, FailingGetAllSyncDataDoesntStopSync) {
syncer::ModelType model_type = syncer::EXTENSION_SETTINGS;
Manifest::Type type = Manifest::TYPE_EXTENSION;
base::StringValue fooValue("fooValue");
base::StringValue barValue("barValue");
TestingValueStoreFactory* testing_factory = new TestingValueStoreFactory();
storage_factory_->Reset(testing_factory);
ValueStore* good = AddExtensionAndGetStorage("good", type);
ValueStore* bad = AddExtensionAndGetStorage("bad", type);
good->Set(DEFAULTS, "foo", fooValue);
bad->Set(DEFAULTS, "foo", fooValue);
testing_factory->GetExisting("bad")->set_error_code(ValueStore::CORRUPTION);
{
syncer::SyncDataList all_sync_data =
GetSyncableService(model_type)->GetAllSyncData(model_type);
EXPECT_EQ(1u, all_sync_data.size());
EXPECT_EQ("good/foo", syncer::SyncDataLocal(all_sync_data[0]).GetTag());
}
testing_factory->GetExisting("bad")->set_error_code(ValueStore::OK);
GetSyncableService(model_type)->MergeDataAndStartSyncing(
model_type,
syncer::SyncDataList(),
sync_processor_wrapper_.PassAs<syncer::SyncChangeProcessor>(),
scoped_ptr<syncer::SyncErrorFactory>(new syncer::SyncErrorFactoryMock()));
EXPECT_EQ(
syncer::SyncChange::ACTION_ADD,
sync_processor_->GetOnlyChange("good", "foo").change_type());
EXPECT_EQ(
syncer::SyncChange::ACTION_ADD,
sync_processor_->GetOnlyChange("bad", "foo").change_type());
EXPECT_EQ(2u, sync_processor_->changes().size());
sync_processor_->ClearChanges();
good->Set(DEFAULTS, "bar", barValue);
bad->Set(DEFAULTS, "bar", barValue);
EXPECT_EQ(
syncer::SyncChange::ACTION_ADD,
sync_processor_->GetOnlyChange("good", "bar").change_type());
EXPECT_EQ(
syncer::SyncChange::ACTION_ADD,
sync_processor_->GetOnlyChange("bad", "bar").change_type());
EXPECT_EQ(2u, sync_processor_->changes().size());
}
TEST_F(ExtensionSettingsSyncTest, FailureToReadChangesToPushDisablesSync) {
syncer::ModelType model_type = syncer::APP_SETTINGS;
Manifest::Type type = Manifest::TYPE_LEGACY_PACKAGED_APP;
base::StringValue fooValue("fooValue");
base::StringValue barValue("barValue");
TestingValueStoreFactory* testing_factory = new TestingValueStoreFactory();
storage_factory_->Reset(testing_factory);
ValueStore* good = AddExtensionAndGetStorage("good", type);
ValueStore* bad = AddExtensionAndGetStorage("bad", type);
good->Set(DEFAULTS, "foo", fooValue);
bad->Set(DEFAULTS, "foo", fooValue);
testing_factory->GetExisting("bad")->set_error_code(ValueStore::CORRUPTION);
GetSyncableService(model_type)->MergeDataAndStartSyncing(
model_type,
syncer::SyncDataList(),
sync_processor_wrapper_.PassAs<syncer::SyncChangeProcessor>(),
scoped_ptr<syncer::SyncErrorFactory>(new syncer::SyncErrorFactoryMock()));
testing_factory->GetExisting("bad")->set_error_code(ValueStore::OK);
EXPECT_EQ(
syncer::SyncChange::ACTION_ADD,
sync_processor_->GetOnlyChange("good", "foo").change_type());
EXPECT_EQ(1u, sync_processor_->changes().size());
sync_processor_->ClearChanges();
good->Set(DEFAULTS, "bar", barValue);
bad->Set(DEFAULTS, "bar", barValue);
EXPECT_EQ(
syncer::SyncChange::ACTION_ADD,
sync_processor_->GetOnlyChange("good", "bar").change_type());
EXPECT_EQ(1u, sync_processor_->changes().size());
{
syncer::SyncChangeList change_list;
change_list.push_back(settings_sync_util::CreateUpdate(
"good", "foo", barValue, model_type));
change_list.push_back(settings_sync_util::CreateAdd(
"bad", "foo", barValue, model_type));
GetSyncableService(model_type)->ProcessSyncChanges(FROM_HERE, change_list);
}
{
base::DictionaryValue dict;
dict.Set("foo", barValue.DeepCopy());
dict.Set("bar", barValue.DeepCopy());
EXPECT_PRED_FORMAT2(SettingsEq, dict, good->Get());
}
{
base::DictionaryValue dict;
dict.Set("foo", fooValue.DeepCopy());
dict.Set("bar", barValue.DeepCopy());
EXPECT_PRED_FORMAT2(SettingsEq, dict, bad->Get());
}
sync_processor_->ClearChanges();
GetSyncableService(model_type)->StopSyncing(model_type);
sync_processor_wrapper_.reset(
new syncer::SyncChangeProcessorWrapperForTest(sync_processor_.get()));
GetSyncableService(model_type)->MergeDataAndStartSyncing(
model_type,
syncer::SyncDataList(),
sync_processor_wrapper_.PassAs<syncer::SyncChangeProcessor>(),
scoped_ptr<syncer::SyncErrorFactory>(new syncer::SyncErrorFactoryMock()));
EXPECT_EQ(
syncer::SyncChange::ACTION_ADD,
sync_processor_->GetOnlyChange("good", "foo").change_type());
EXPECT_EQ(
syncer::SyncChange::ACTION_ADD,
sync_processor_->GetOnlyChange("good", "bar").change_type());
EXPECT_EQ(
syncer::SyncChange::ACTION_ADD,
sync_processor_->GetOnlyChange("bad", "foo").change_type());
EXPECT_EQ(
syncer::SyncChange::ACTION_ADD,
sync_processor_->GetOnlyChange("bad", "bar").change_type());
EXPECT_EQ(4u, sync_processor_->changes().size());
sync_processor_->ClearChanges();
good->Set(DEFAULTS, "bar", fooValue);
bad->Set(DEFAULTS, "bar", fooValue);
EXPECT_EQ(
syncer::SyncChange::ACTION_UPDATE,
sync_processor_->GetOnlyChange("good", "bar").change_type());
EXPECT_EQ(
syncer::SyncChange::ACTION_UPDATE,
sync_processor_->GetOnlyChange("good", "bar").change_type());
EXPECT_EQ(2u, sync_processor_->changes().size());
}
TEST_F(ExtensionSettingsSyncTest, FailureToPushLocalStateDisablesSync) {
syncer::ModelType model_type = syncer::EXTENSION_SETTINGS;
Manifest::Type type = Manifest::TYPE_EXTENSION;
base::StringValue fooValue("fooValue");
base::StringValue barValue("barValue");
TestingValueStoreFactory* testing_factory = new TestingValueStoreFactory();
storage_factory_->Reset(testing_factory);
ValueStore* good = AddExtensionAndGetStorage("good", type);
ValueStore* bad = AddExtensionAndGetStorage("bad", type);
bad->Set(DEFAULTS, "foo", fooValue);
sync_processor_->set_fail_all_requests(true);
GetSyncableService(model_type)->MergeDataAndStartSyncing(
model_type,
syncer::SyncDataList(),
sync_processor_wrapper_.PassAs<syncer::SyncChangeProcessor>(),
scoped_ptr<syncer::SyncErrorFactory>(new syncer::SyncErrorFactoryMock()));
sync_processor_->set_fail_all_requests(false);
sync_processor_->ClearChanges();
good->Set(DEFAULTS, "foo", barValue);
bad->Set(DEFAULTS, "foo", barValue);
EXPECT_EQ(
syncer::SyncChange::ACTION_ADD,
sync_processor_->GetOnlyChange("good", "foo").change_type());
EXPECT_EQ(1u, sync_processor_->changes().size());
{
syncer::SyncChangeList change_list;
change_list.push_back(settings_sync_util::CreateAdd(
"good", "bar", barValue, model_type));
change_list.push_back(settings_sync_util::CreateAdd(
"bad", "bar", barValue, model_type));
GetSyncableService(model_type)->ProcessSyncChanges(FROM_HERE, change_list);
}
{
base::DictionaryValue dict;
dict.Set("foo", barValue.DeepCopy());
dict.Set("bar", barValue.DeepCopy());
EXPECT_PRED_FORMAT2(SettingsEq, dict, good->Get());
}
{
base::DictionaryValue dict;
dict.Set("foo", barValue.DeepCopy());
EXPECT_PRED_FORMAT2(SettingsEq, dict, bad->Get());
}
sync_processor_->ClearChanges();
GetSyncableService(model_type)->StopSyncing(model_type);
sync_processor_wrapper_.reset(
new syncer::SyncChangeProcessorWrapperForTest(sync_processor_.get()));
GetSyncableService(model_type)->MergeDataAndStartSyncing(
model_type,
syncer::SyncDataList(),
sync_processor_wrapper_.PassAs<syncer::SyncChangeProcessor>(),
scoped_ptr<syncer::SyncErrorFactory>(new syncer::SyncErrorFactoryMock()));
EXPECT_EQ(
syncer::SyncChange::ACTION_ADD,
sync_processor_->GetOnlyChange("good", "foo").change_type());
EXPECT_EQ(
syncer::SyncChange::ACTION_ADD,
sync_processor_->GetOnlyChange("good", "bar").change_type());
EXPECT_EQ(
syncer::SyncChange::ACTION_ADD,
sync_processor_->GetOnlyChange("bad", "foo").change_type());
EXPECT_EQ(3u, sync_processor_->changes().size());
sync_processor_->ClearChanges();
good->Set(DEFAULTS, "foo", fooValue);
bad->Set(DEFAULTS, "foo", fooValue);
EXPECT_EQ(
syncer::SyncChange::ACTION_UPDATE,
sync_processor_->GetOnlyChange("good", "foo").change_type());
EXPECT_EQ(
syncer::SyncChange::ACTION_UPDATE,
sync_processor_->GetOnlyChange("good", "foo").change_type());
EXPECT_EQ(2u, sync_processor_->changes().size());
}
TEST_F(ExtensionSettingsSyncTest, FailureToPushLocalChangeDisablesSync) {
syncer::ModelType model_type = syncer::EXTENSION_SETTINGS;
Manifest::Type type = Manifest::TYPE_EXTENSION;
base::StringValue fooValue("fooValue");
base::StringValue barValue("barValue");
TestingValueStoreFactory* testing_factory = new TestingValueStoreFactory();
storage_factory_->Reset(testing_factory);
ValueStore* good = AddExtensionAndGetStorage("good", type);
ValueStore* bad = AddExtensionAndGetStorage("bad", type);
GetSyncableService(model_type)->MergeDataAndStartSyncing(
model_type,
syncer::SyncDataList(),
sync_processor_wrapper_.PassAs<syncer::SyncChangeProcessor>(),
scoped_ptr<syncer::SyncErrorFactory>(new syncer::SyncErrorFactoryMock()));
good->Set(DEFAULTS, "foo", fooValue);
sync_processor_->set_fail_all_requests(true);
bad->Set(DEFAULTS, "foo", fooValue);
sync_processor_->set_fail_all_requests(false);
EXPECT_EQ(
syncer::SyncChange::ACTION_ADD,
sync_processor_->GetOnlyChange("good", "foo").change_type());
EXPECT_EQ(1u, sync_processor_->changes().size());
sync_processor_->ClearChanges();
good->Set(DEFAULTS, "foo", barValue);
bad->Set(DEFAULTS, "foo", barValue);
EXPECT_EQ(
syncer::SyncChange::ACTION_UPDATE,
sync_processor_->GetOnlyChange("good", "foo").change_type());
EXPECT_EQ(1u, sync_processor_->changes().size());
{
syncer::SyncChangeList change_list;
change_list.push_back(settings_sync_util::CreateAdd(
"good", "bar", barValue, model_type));
change_list.push_back(settings_sync_util::CreateAdd(
"bad", "bar", barValue, model_type));
GetSyncableService(model_type)->ProcessSyncChanges(FROM_HERE, change_list);
}
{
base::DictionaryValue dict;
dict.Set("foo", barValue.DeepCopy());
dict.Set("bar", barValue.DeepCopy());
EXPECT_PRED_FORMAT2(SettingsEq, dict, good->Get());
}
{
base::DictionaryValue dict;
dict.Set("foo", barValue.DeepCopy());
EXPECT_PRED_FORMAT2(SettingsEq, dict, bad->Get());
}
sync_processor_->ClearChanges();
GetSyncableService(model_type)->StopSyncing(model_type);
sync_processor_wrapper_.reset(
new syncer::SyncChangeProcessorWrapperForTest(sync_processor_.get()));
GetSyncableService(model_type)->MergeDataAndStartSyncing(
model_type,
syncer::SyncDataList(),
sync_processor_wrapper_.PassAs<syncer::SyncChangeProcessor>(),
scoped_ptr<syncer::SyncErrorFactory>(new syncer::SyncErrorFactoryMock()));
EXPECT_EQ(
syncer::SyncChange::ACTION_ADD,
sync_processor_->GetOnlyChange("good", "foo").change_type());
EXPECT_EQ(
syncer::SyncChange::ACTION_ADD,
sync_processor_->GetOnlyChange("good", "bar").change_type());
EXPECT_EQ(
syncer::SyncChange::ACTION_ADD,
sync_processor_->GetOnlyChange("bad", "foo").change_type());
EXPECT_EQ(3u, sync_processor_->changes().size());
sync_processor_->ClearChanges();
good->Set(DEFAULTS, "foo", fooValue);
bad->Set(DEFAULTS, "foo", fooValue);
EXPECT_EQ(
syncer::SyncChange::ACTION_UPDATE,
sync_processor_->GetOnlyChange("good", "foo").change_type());
EXPECT_EQ(
syncer::SyncChange::ACTION_UPDATE,
sync_processor_->GetOnlyChange("good", "foo").change_type());
EXPECT_EQ(2u, sync_processor_->changes().size());
}
TEST_F(ExtensionSettingsSyncTest,
LargeOutgoingChangeRejectedButIncomingAccepted) {
syncer::ModelType model_type = syncer::APP_SETTINGS;
Manifest::Type type = Manifest::TYPE_LEGACY_PACKAGED_APP;
std::string string_5k;
for (size_t i = 0; i < 5000; ++i) {
string_5k.append("a");
}
base::StringValue large_value(string_5k);
GetSyncableService(model_type)->MergeDataAndStartSyncing(
model_type,
syncer::SyncDataList(),
sync_processor_wrapper_.PassAs<syncer::SyncChangeProcessor>(),
scoped_ptr<syncer::SyncErrorFactory>(new syncer::SyncErrorFactoryMock()));
ValueStore* storage1 = AddExtensionAndGetStorage("s1", type);
EXPECT_TRUE(storage1->Set(DEFAULTS, "large_value", large_value)->HasError());
EXPECT_EQ(0u, sync_processor_->changes().size());
ValueStore* storage2 = AddExtensionAndGetStorage("s2", type);
{
syncer::SyncChangeList change_list;
change_list.push_back(settings_sync_util::CreateAdd(
"s1", "large_value", large_value, model_type));
change_list.push_back(settings_sync_util::CreateAdd(
"s2", "large_value", large_value, model_type));
GetSyncableService(model_type)->ProcessSyncChanges(FROM_HERE, change_list);
}
{
base::DictionaryValue expected;
expected.Set("large_value", large_value.DeepCopy());
EXPECT_PRED_FORMAT2(SettingsEq, expected, storage1->Get());
EXPECT_PRED_FORMAT2(SettingsEq, expected, storage2->Get());
}
GetSyncableService(model_type)->StopSyncing(model_type);
}
TEST_F(ExtensionSettingsSyncTest, Dots) {
syncer::ModelType model_type = syncer::EXTENSION_SETTINGS;
Manifest::Type type = Manifest::TYPE_EXTENSION;
ValueStore* storage = AddExtensionAndGetStorage("ext", type);
{
syncer::SyncDataList sync_data_list;
scoped_ptr<base::Value> string_value(new base::StringValue("value"));
sync_data_list.push_back(settings_sync_util::CreateData(
"ext", "key.with.dot", *string_value, model_type));
GetSyncableService(model_type)->MergeDataAndStartSyncing(
model_type,
sync_data_list,
sync_processor_wrapper_.PassAs<syncer::SyncChangeProcessor>(),
scoped_ptr<syncer::SyncErrorFactory>(
new syncer::SyncErrorFactoryMock()));
}
{
ValueStore::ReadResult data = storage->Get();
ASSERT_FALSE(data->HasError());
base::DictionaryValue expected_data;
expected_data.SetWithoutPathExpansion(
"key.with.dot",
new base::StringValue("value"));
EXPECT_TRUE(base::Value::Equals(&expected_data, &data->settings()));
}
{
scoped_ptr<base::Value> string_value(new base::StringValue("spot"));
storage->Set(DEFAULTS, "key.with.spot", *string_value);
ASSERT_EQ(1u, sync_processor_->changes().size());
SettingSyncData sync_data = sync_processor_->changes()[0];
EXPECT_EQ(syncer::SyncChange::ACTION_ADD, sync_data.change_type());
EXPECT_EQ("ext", sync_data.extension_id());
EXPECT_EQ("key.with.spot", sync_data.key());
EXPECT_TRUE(sync_data.value().Equals(string_value.get()));
}
}
}