settings_sync_unittest.cc revision a1401311d1ab56c4ed0a474bd38c108f75cb0cd9
1// Copyright (c) 2012 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 "base/bind.h"
6#include "base/files/scoped_temp_dir.h"
7#include "base/json/json_reader.h"
8#include "base/json/json_writer.h"
9#include "base/memory/scoped_ptr.h"
10#include "base/message_loop/message_loop.h"
11#include "chrome/browser/extensions/api/storage/settings_sync_util.h"
12#include "chrome/browser/extensions/api/storage/sync_value_store_cache.h"
13#include "chrome/browser/extensions/api/storage/syncable_settings_storage.h"
14#include "content/public/test/test_browser_thread.h"
15#include "extensions/browser/api/storage/leveldb_settings_storage_factory.h"
16#include "extensions/browser/api/storage/settings_storage_factory.h"
17#include "extensions/browser/api/storage/settings_test_util.h"
18#include "extensions/browser/api/storage/storage_frontend.h"
19#include "extensions/browser/extension_system.h"
20#include "extensions/browser/value_store/testing_value_store.h"
21#include "extensions/common/manifest.h"
22#include "sync/api/sync_change_processor.h"
23#include "sync/api/sync_change_processor_wrapper_for_test.h"
24#include "sync/api/sync_error_factory.h"
25#include "sync/api/sync_error_factory_mock.h"
26#include "testing/gtest/include/gtest/gtest.h"
27
28using base::DictionaryValue;
29using base::ListValue;
30using base::Value;
31using content::BrowserThread;
32
33namespace extensions {
34
35namespace util = settings_test_util;
36
37namespace {
38
39// To save typing ValueStore::DEFAULTS everywhere.
40const ValueStore::WriteOptions DEFAULTS = ValueStore::DEFAULTS;
41
42// Gets the pretty-printed JSON for a value.
43static std::string GetJson(const base::Value& value) {
44  std::string json;
45  base::JSONWriter::WriteWithOptions(&value,
46                                     base::JSONWriter::OPTIONS_PRETTY_PRINT,
47                                     &json);
48  return json;
49}
50
51// Returns whether two Values are equal.
52testing::AssertionResult ValuesEq(
53    const char* _1, const char* _2,
54    const base::Value* expected,
55    const base::Value* actual) {
56  if (expected == actual) {
57    return testing::AssertionSuccess();
58  }
59  if (!expected && actual) {
60    return testing::AssertionFailure() <<
61        "Expected NULL, actual: " << GetJson(*actual);
62  }
63  if (expected && !actual) {
64    return testing::AssertionFailure() <<
65        "Expected: " << GetJson(*expected) << ", actual NULL";
66  }
67  if (!expected->Equals(actual)) {
68    return testing::AssertionFailure() <<
69        "Expected: " << GetJson(*expected) << ", actual: " << GetJson(*actual);
70  }
71  return testing::AssertionSuccess();
72}
73
74// Returns whether the result of a storage operation is an expected value.
75// Logs when different.
76testing::AssertionResult SettingsEq(
77    const char* _1, const char* _2,
78    const base::DictionaryValue& expected,
79    ValueStore::ReadResult actual) {
80  if (actual->HasError()) {
81    return testing::AssertionFailure() <<
82        "Expected: " << expected <<
83        ", actual has error: " << actual->error().message;
84  }
85  return ValuesEq(_1, _2, &expected, &actual->settings());
86}
87
88// SyncChangeProcessor which just records the changes made, accessed after
89// being converted to the more useful SettingSyncData via changes().
90class MockSyncChangeProcessor : public syncer::SyncChangeProcessor {
91 public:
92  MockSyncChangeProcessor() : fail_all_requests_(false) {}
93
94  // syncer::SyncChangeProcessor implementation.
95  virtual syncer::SyncError ProcessSyncChanges(
96      const tracked_objects::Location& from_here,
97      const syncer::SyncChangeList& change_list) OVERRIDE {
98    if (fail_all_requests_) {
99      return syncer::SyncError(
100          FROM_HERE,
101          syncer::SyncError::DATATYPE_ERROR,
102          "MockSyncChangeProcessor: configured to fail",
103          change_list[0].sync_data().GetDataType());
104    }
105    for (syncer::SyncChangeList::const_iterator it = change_list.begin();
106        it != change_list.end(); ++it) {
107      changes_.push_back(SettingSyncData(*it));
108    }
109    return syncer::SyncError();
110  }
111
112  virtual syncer::SyncDataList GetAllSyncData(syncer::ModelType type) const
113      OVERRIDE {
114    return syncer::SyncDataList();
115  }
116
117  // Mock methods.
118
119  const SettingSyncDataList& changes() { return changes_; }
120
121  void ClearChanges() {
122    changes_.clear();
123  }
124
125  void set_fail_all_requests(bool fail_all_requests) {
126    fail_all_requests_ = fail_all_requests;
127  }
128
129  // Returns the only change for a given extension setting.  If there is not
130  // exactly 1 change for that key, a test assertion will fail.
131  SettingSyncData GetOnlyChange(
132      const std::string& extension_id, const std::string& key) {
133    SettingSyncDataList matching_changes;
134    for (SettingSyncDataList::iterator it = changes_.begin();
135        it != changes_.end(); ++it) {
136      if (it->extension_id() == extension_id && it->key() == key) {
137        matching_changes.push_back(*it);
138      }
139    }
140    if (matching_changes.empty()) {
141      ADD_FAILURE() << "No matching changes for " << extension_id << "/" <<
142          key << " (out of " << changes_.size() << ")";
143      return SettingSyncData(syncer::SyncChange::ACTION_INVALID,
144                             std::string(),
145                             std::string(),
146                             scoped_ptr<base::Value>(
147                                 new base::DictionaryValue()));
148    }
149    if (matching_changes.size() != 1u) {
150      ADD_FAILURE() << matching_changes.size() << " matching changes for " <<
151           extension_id << "/" << key << " (out of " << changes_.size() << ")";
152    }
153    return matching_changes[0];
154  }
155
156 private:
157  SettingSyncDataList changes_;
158  bool fail_all_requests_;
159};
160
161// SettingsStorageFactory which always returns TestingValueStore objects,
162// and allows individually created objects to be returned.
163class TestingValueStoreFactory : public SettingsStorageFactory {
164 public:
165  TestingValueStore* GetExisting(const std::string& extension_id) {
166    DCHECK(created_.count(extension_id));
167    return created_[extension_id];
168  }
169
170  // SettingsStorageFactory implementation.
171  virtual ValueStore* Create(const base::FilePath& base_path,
172                             const std::string& extension_id) OVERRIDE {
173    TestingValueStore* new_storage = new TestingValueStore();
174    DCHECK(!created_.count(extension_id));
175    created_[extension_id] = new_storage;
176    return new_storage;
177  }
178
179  // Testing value stores don't actually create a real database. Don't delete
180  // any files.
181  virtual void DeleteDatabaseIfExists(
182      const base::FilePath& base_path,
183      const std::string& extension_id) OVERRIDE {}
184
185 private:
186  // SettingsStorageFactory is refcounted.
187  virtual ~TestingValueStoreFactory() {}
188
189  // None of these storage areas are owned by this factory, so care must be
190  // taken when calling GetExisting.
191  std::map<std::string, TestingValueStore*> created_;
192};
193
194}  // namespace
195
196class ExtensionSettingsSyncTest : public testing::Test {
197 public:
198  ExtensionSettingsSyncTest()
199      : ui_thread_(BrowserThread::UI, base::MessageLoop::current()),
200        file_thread_(BrowserThread::FILE, base::MessageLoop::current()),
201        storage_factory_(new util::ScopedSettingsStorageFactory()),
202        sync_processor_(new MockSyncChangeProcessor),
203        sync_processor_wrapper_(new syncer::SyncChangeProcessorWrapperForTest(
204            sync_processor_.get())) {}
205
206  virtual void SetUp() OVERRIDE {
207    ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
208    profile_.reset(new util::MockProfile(temp_dir_.path()));
209    storage_factory_->Reset(new LeveldbSettingsStorageFactory());
210    frontend_.reset(
211        StorageFrontend::CreateForTesting(storage_factory_, profile_.get()));
212  }
213
214  virtual void TearDown() OVERRIDE {
215    frontend_.reset();
216    profile_.reset();
217    // Execute any pending deletion tasks.
218    message_loop_.RunUntilIdle();
219  }
220
221 protected:
222  // Adds a record of an extension or app to the extension service, then returns
223  // its storage area.
224  ValueStore* AddExtensionAndGetStorage(
225      const std::string& id, Manifest::Type type) {
226    scoped_refptr<const Extension> extension =
227        util::AddExtensionWithId(profile_.get(), id, type);
228    return util::GetStorage(extension, frontend_.get());
229  }
230
231  // Gets the syncer::SyncableService for the given sync type.
232  syncer::SyncableService* GetSyncableService(syncer::ModelType model_type) {
233    base::MessageLoop::current()->RunUntilIdle();
234    SyncValueStoreCache* sync_cache = static_cast<SyncValueStoreCache*>(
235        frontend_->GetValueStoreCache(settings_namespace::SYNC));
236    return sync_cache->GetSyncableService(model_type);
237  }
238
239  // Gets all the sync data from the SyncableService for a sync type as a map
240  // from extension id to its sync data.
241  std::map<std::string, SettingSyncDataList> GetAllSyncData(
242      syncer::ModelType model_type) {
243    syncer::SyncDataList as_list =
244        GetSyncableService(model_type)->GetAllSyncData(model_type);
245    std::map<std::string, SettingSyncDataList> as_map;
246    for (syncer::SyncDataList::iterator it = as_list.begin();
247        it != as_list.end(); ++it) {
248      SettingSyncData sync_data(*it);
249      as_map[sync_data.extension_id()].push_back(sync_data);
250    }
251    return as_map;
252  }
253
254  // Need these so that the DCHECKs for running on FILE or UI threads pass.
255  base::MessageLoop message_loop_;
256  content::TestBrowserThread ui_thread_;
257  content::TestBrowserThread file_thread_;
258
259  base::ScopedTempDir temp_dir_;
260  scoped_ptr<util::MockProfile> profile_;
261  scoped_ptr<StorageFrontend> frontend_;
262  scoped_refptr<util::ScopedSettingsStorageFactory> storage_factory_;
263  scoped_ptr<MockSyncChangeProcessor> sync_processor_;
264  scoped_ptr<syncer::SyncChangeProcessorWrapperForTest> sync_processor_wrapper_;
265};
266
267// Get a semblance of coverage for both EXTENSION_SETTINGS and APP_SETTINGS
268// sync by roughly alternative which one to test.
269
270TEST_F(ExtensionSettingsSyncTest, NoDataDoesNotInvokeSync) {
271  syncer::ModelType model_type = syncer::EXTENSION_SETTINGS;
272  Manifest::Type type = Manifest::TYPE_EXTENSION;
273
274  EXPECT_EQ(0u, GetAllSyncData(model_type).size());
275
276  // Have one extension created before sync is set up, the other created after.
277  AddExtensionAndGetStorage("s1", type);
278  EXPECT_EQ(0u, GetAllSyncData(model_type).size());
279
280  GetSyncableService(model_type)->MergeDataAndStartSyncing(
281      model_type,
282      syncer::SyncDataList(),
283      sync_processor_wrapper_.PassAs<syncer::SyncChangeProcessor>(),
284      scoped_ptr<syncer::SyncErrorFactory>(new syncer::SyncErrorFactoryMock()));
285
286  AddExtensionAndGetStorage("s2", type);
287  EXPECT_EQ(0u, GetAllSyncData(model_type).size());
288
289  GetSyncableService(model_type)->StopSyncing(model_type);
290
291  EXPECT_EQ(0u, sync_processor_->changes().size());
292  EXPECT_EQ(0u, GetAllSyncData(model_type).size());
293}
294
295TEST_F(ExtensionSettingsSyncTest, InSyncDataDoesNotInvokeSync) {
296  syncer::ModelType model_type = syncer::APP_SETTINGS;
297  Manifest::Type type = Manifest::TYPE_LEGACY_PACKAGED_APP;
298
299  base::StringValue value1("fooValue");
300  base::ListValue value2;
301  value2.Append(new base::StringValue("barValue"));
302
303  ValueStore* storage1 = AddExtensionAndGetStorage("s1", type);
304  ValueStore* storage2 = AddExtensionAndGetStorage("s2", type);
305
306  storage1->Set(DEFAULTS, "foo", value1);
307  storage2->Set(DEFAULTS, "bar", value2);
308
309  std::map<std::string, SettingSyncDataList> all_sync_data =
310      GetAllSyncData(model_type);
311  EXPECT_EQ(2u, all_sync_data.size());
312  EXPECT_EQ(1u, all_sync_data["s1"].size());
313  EXPECT_PRED_FORMAT2(ValuesEq, &value1, &all_sync_data["s1"][0].value());
314  EXPECT_EQ(1u, all_sync_data["s2"].size());
315  EXPECT_PRED_FORMAT2(ValuesEq, &value2, &all_sync_data["s2"][0].value());
316
317  syncer::SyncDataList sync_data;
318  sync_data.push_back(settings_sync_util::CreateData(
319      "s1", "foo", value1, model_type));
320  sync_data.push_back(settings_sync_util::CreateData(
321      "s2", "bar", value2, model_type));
322
323  GetSyncableService(model_type)->MergeDataAndStartSyncing(
324      model_type,
325      sync_data,
326      sync_processor_wrapper_.PassAs<syncer::SyncChangeProcessor>(),
327      scoped_ptr<syncer::SyncErrorFactory>(new syncer::SyncErrorFactoryMock()));
328
329  // Already in sync, so no changes.
330  EXPECT_EQ(0u, sync_processor_->changes().size());
331
332  // Regression test: not-changing the synced value shouldn't result in a sync
333  // change, and changing the synced value should result in an update.
334  storage1->Set(DEFAULTS, "foo", value1);
335  EXPECT_EQ(0u, sync_processor_->changes().size());
336
337  storage1->Set(DEFAULTS, "foo", value2);
338  EXPECT_EQ(1u, sync_processor_->changes().size());
339  SettingSyncData change = sync_processor_->GetOnlyChange("s1", "foo");
340  EXPECT_EQ(syncer::SyncChange::ACTION_UPDATE, change.change_type());
341  EXPECT_TRUE(value2.Equals(&change.value()));
342
343  GetSyncableService(model_type)->StopSyncing(model_type);
344}
345
346TEST_F(ExtensionSettingsSyncTest, LocalDataWithNoSyncDataIsPushedToSync) {
347  syncer::ModelType model_type = syncer::EXTENSION_SETTINGS;
348  Manifest::Type type = Manifest::TYPE_EXTENSION;
349
350  base::StringValue value1("fooValue");
351  base::ListValue value2;
352  value2.Append(new base::StringValue("barValue"));
353
354  ValueStore* storage1 = AddExtensionAndGetStorage("s1", type);
355  ValueStore* storage2 = AddExtensionAndGetStorage("s2", type);
356
357  storage1->Set(DEFAULTS, "foo", value1);
358  storage2->Set(DEFAULTS, "bar", value2);
359
360  GetSyncableService(model_type)->MergeDataAndStartSyncing(
361      model_type,
362      syncer::SyncDataList(),
363      sync_processor_wrapper_.PassAs<syncer::SyncChangeProcessor>(),
364      scoped_ptr<syncer::SyncErrorFactory>(new syncer::SyncErrorFactoryMock()));
365
366  // All settings should have been pushed to sync.
367  EXPECT_EQ(2u, sync_processor_->changes().size());
368  SettingSyncData change = sync_processor_->GetOnlyChange("s1", "foo");
369  EXPECT_EQ(syncer::SyncChange::ACTION_ADD, change.change_type());
370  EXPECT_TRUE(value1.Equals(&change.value()));
371  change = sync_processor_->GetOnlyChange("s2", "bar");
372  EXPECT_EQ(syncer::SyncChange::ACTION_ADD, change.change_type());
373  EXPECT_TRUE(value2.Equals(&change.value()));
374
375  GetSyncableService(model_type)->StopSyncing(model_type);
376}
377
378TEST_F(ExtensionSettingsSyncTest, AnySyncDataOverwritesLocalData) {
379  syncer::ModelType model_type = syncer::APP_SETTINGS;
380  Manifest::Type type = Manifest::TYPE_LEGACY_PACKAGED_APP;
381
382  base::StringValue value1("fooValue");
383  base::ListValue value2;
384  value2.Append(new base::StringValue("barValue"));
385
386  // Maintain dictionaries mirrored to the expected values of the settings in
387  // each storage area.
388  base::DictionaryValue expected1, expected2;
389
390  // Pre-populate one of the storage areas.
391  ValueStore* storage1 = AddExtensionAndGetStorage("s1", type);
392  storage1->Set(DEFAULTS, "overwriteMe", value1);
393
394  syncer::SyncDataList sync_data;
395  sync_data.push_back(settings_sync_util::CreateData(
396      "s1", "foo", value1, model_type));
397  sync_data.push_back(settings_sync_util::CreateData(
398      "s2", "bar", value2, model_type));
399  GetSyncableService(model_type)->MergeDataAndStartSyncing(
400      model_type,
401      sync_data,
402      sync_processor_wrapper_.PassAs<syncer::SyncChangeProcessor>(),
403      scoped_ptr<syncer::SyncErrorFactory>(new syncer::SyncErrorFactoryMock()));
404  expected1.Set("foo", value1.DeepCopy());
405  expected2.Set("bar", value2.DeepCopy());
406
407  ValueStore* storage2 = AddExtensionAndGetStorage("s2", type);
408
409  // All changes should be local, so no sync changes.
410  EXPECT_EQ(0u, sync_processor_->changes().size());
411
412  // Sync settings should have been pushed to local settings.
413  EXPECT_PRED_FORMAT2(SettingsEq, expected1, storage1->Get());
414  EXPECT_PRED_FORMAT2(SettingsEq, expected2, storage2->Get());
415
416  GetSyncableService(model_type)->StopSyncing(model_type);
417}
418
419TEST_F(ExtensionSettingsSyncTest, ProcessSyncChanges) {
420  syncer::ModelType model_type = syncer::EXTENSION_SETTINGS;
421  Manifest::Type type = Manifest::TYPE_EXTENSION;
422
423  base::StringValue value1("fooValue");
424  base::ListValue value2;
425  value2.Append(new base::StringValue("barValue"));
426
427  // Maintain dictionaries mirrored to the expected values of the settings in
428  // each storage area.
429  base::DictionaryValue expected1, expected2;
430
431  // Make storage1 initialised from local data, storage2 initialised from sync.
432  ValueStore* storage1 = AddExtensionAndGetStorage("s1", type);
433  ValueStore* storage2 = AddExtensionAndGetStorage("s2", type);
434
435  storage1->Set(DEFAULTS, "foo", value1);
436  expected1.Set("foo", value1.DeepCopy());
437
438  syncer::SyncDataList sync_data;
439  sync_data.push_back(settings_sync_util::CreateData(
440      "s2", "bar", value2, model_type));
441
442  GetSyncableService(model_type)->MergeDataAndStartSyncing(
443      model_type,
444      sync_data,
445      sync_processor_wrapper_.PassAs<syncer::SyncChangeProcessor>(),
446      scoped_ptr<syncer::SyncErrorFactory>(new syncer::SyncErrorFactoryMock()));
447  expected2.Set("bar", value2.DeepCopy());
448
449  // Make sync add some settings.
450  syncer::SyncChangeList change_list;
451  change_list.push_back(settings_sync_util::CreateAdd(
452      "s1", "bar", value2, model_type));
453  change_list.push_back(settings_sync_util::CreateAdd(
454      "s2", "foo", value1, model_type));
455  GetSyncableService(model_type)->ProcessSyncChanges(FROM_HERE, change_list);
456  expected1.Set("bar", value2.DeepCopy());
457  expected2.Set("foo", value1.DeepCopy());
458
459  EXPECT_PRED_FORMAT2(SettingsEq, expected1, storage1->Get());
460  EXPECT_PRED_FORMAT2(SettingsEq, expected2, storage2->Get());
461
462  // Make sync update some settings, storage1 the new setting, storage2 the
463  // initial setting.
464  change_list.clear();
465  change_list.push_back(settings_sync_util::CreateUpdate(
466      "s1", "bar", value2, model_type));
467  change_list.push_back(settings_sync_util::CreateUpdate(
468      "s2", "bar", value1, model_type));
469  GetSyncableService(model_type)->ProcessSyncChanges(FROM_HERE, change_list);
470  expected1.Set("bar", value2.DeepCopy());
471  expected2.Set("bar", value1.DeepCopy());
472
473  EXPECT_PRED_FORMAT2(SettingsEq, expected1, storage1->Get());
474  EXPECT_PRED_FORMAT2(SettingsEq, expected2, storage2->Get());
475
476  // Make sync remove some settings, storage1 the initial setting, storage2 the
477  // new setting.
478  change_list.clear();
479  change_list.push_back(settings_sync_util::CreateDelete(
480      "s1", "foo", model_type));
481  change_list.push_back(settings_sync_util::CreateDelete(
482      "s2", "foo", model_type));
483  GetSyncableService(model_type)->ProcessSyncChanges(FROM_HERE, change_list);
484  expected1.Remove("foo", NULL);
485  expected2.Remove("foo", NULL);
486
487  EXPECT_PRED_FORMAT2(SettingsEq, expected1, storage1->Get());
488  EXPECT_PRED_FORMAT2(SettingsEq, expected2, storage2->Get());
489
490  GetSyncableService(model_type)->StopSyncing(model_type);
491}
492
493TEST_F(ExtensionSettingsSyncTest, PushToSync) {
494  syncer::ModelType model_type = syncer::APP_SETTINGS;
495  Manifest::Type type = Manifest::TYPE_LEGACY_PACKAGED_APP;
496
497  base::StringValue value1("fooValue");
498  base::ListValue value2;
499  value2.Append(new base::StringValue("barValue"));
500
501  // Make storage1/2 initialised from local data, storage3/4 initialised from
502  // sync.
503  ValueStore* storage1 = AddExtensionAndGetStorage("s1", type);
504  ValueStore* storage2 = AddExtensionAndGetStorage("s2", type);
505  ValueStore* storage3 = AddExtensionAndGetStorage("s3", type);
506  ValueStore* storage4 = AddExtensionAndGetStorage("s4", type);
507
508  storage1->Set(DEFAULTS, "foo", value1);
509  storage2->Set(DEFAULTS, "foo", value1);
510
511  syncer::SyncDataList sync_data;
512  sync_data.push_back(settings_sync_util::CreateData(
513      "s3", "bar", value2, model_type));
514  sync_data.push_back(settings_sync_util::CreateData(
515      "s4", "bar", value2, model_type));
516
517  GetSyncableService(model_type)->MergeDataAndStartSyncing(
518      model_type,
519      sync_data,
520      sync_processor_wrapper_.PassAs<syncer::SyncChangeProcessor>(),
521      scoped_ptr<syncer::SyncErrorFactory>(new syncer::SyncErrorFactoryMock()));
522
523  // Add something locally.
524  storage1->Set(DEFAULTS, "bar", value2);
525  storage2->Set(DEFAULTS, "bar", value2);
526  storage3->Set(DEFAULTS, "foo", value1);
527  storage4->Set(DEFAULTS, "foo", value1);
528
529  SettingSyncData change = sync_processor_->GetOnlyChange("s1", "bar");
530    EXPECT_EQ(syncer::SyncChange::ACTION_ADD, change.change_type());
531    EXPECT_TRUE(value2.Equals(&change.value()));
532  sync_processor_->GetOnlyChange("s2", "bar");
533    EXPECT_EQ(syncer::SyncChange::ACTION_ADD, change.change_type());
534    EXPECT_TRUE(value2.Equals(&change.value()));
535  change = sync_processor_->GetOnlyChange("s3", "foo");
536    EXPECT_EQ(syncer::SyncChange::ACTION_ADD, change.change_type());
537    EXPECT_TRUE(value1.Equals(&change.value()));
538  change = sync_processor_->GetOnlyChange("s4", "foo");
539    EXPECT_EQ(syncer::SyncChange::ACTION_ADD, change.change_type());
540    EXPECT_TRUE(value1.Equals(&change.value()));
541
542  // Change something locally, storage1/3 the new setting and storage2/4 the
543  // initial setting, for all combinations of local vs sync intialisation and
544  // new vs initial.
545  sync_processor_->ClearChanges();
546  storage1->Set(DEFAULTS, "bar", value1);
547  storage2->Set(DEFAULTS, "foo", value2);
548  storage3->Set(DEFAULTS, "bar", value1);
549  storage4->Set(DEFAULTS, "foo", value2);
550
551  change = sync_processor_->GetOnlyChange("s1", "bar");
552    EXPECT_EQ(syncer::SyncChange::ACTION_UPDATE, change.change_type());
553    EXPECT_TRUE(value1.Equals(&change.value()));
554  change = sync_processor_->GetOnlyChange("s2", "foo");
555    EXPECT_EQ(syncer::SyncChange::ACTION_UPDATE, change.change_type());
556    EXPECT_TRUE(value2.Equals(&change.value()));
557  change = sync_processor_->GetOnlyChange("s3", "bar");
558    EXPECT_EQ(syncer::SyncChange::ACTION_UPDATE, change.change_type());
559    EXPECT_TRUE(value1.Equals(&change.value()));
560  change = sync_processor_->GetOnlyChange("s4", "foo");
561    EXPECT_EQ(syncer::SyncChange::ACTION_UPDATE, change.change_type());
562    EXPECT_TRUE(value2.Equals(&change.value()));
563
564  // Remove something locally, storage1/3 the new setting and storage2/4 the
565  // initial setting, for all combinations of local vs sync intialisation and
566  // new vs initial.
567  sync_processor_->ClearChanges();
568  storage1->Remove("foo");
569  storage2->Remove("bar");
570  storage3->Remove("foo");
571  storage4->Remove("bar");
572
573  EXPECT_EQ(
574      syncer::SyncChange::ACTION_DELETE,
575      sync_processor_->GetOnlyChange("s1", "foo").change_type());
576  EXPECT_EQ(
577      syncer::SyncChange::ACTION_DELETE,
578      sync_processor_->GetOnlyChange("s2", "bar").change_type());
579  EXPECT_EQ(
580      syncer::SyncChange::ACTION_DELETE,
581      sync_processor_->GetOnlyChange("s3", "foo").change_type());
582  EXPECT_EQ(
583      syncer::SyncChange::ACTION_DELETE,
584      sync_processor_->GetOnlyChange("s4", "bar").change_type());
585
586  // Remove some nonexistent settings.
587  sync_processor_->ClearChanges();
588  storage1->Remove("foo");
589  storage2->Remove("bar");
590  storage3->Remove("foo");
591  storage4->Remove("bar");
592
593  EXPECT_EQ(0u, sync_processor_->changes().size());
594
595  // Clear the rest of the settings.  Add the removed ones back first so that
596  // more than one setting is cleared.
597  storage1->Set(DEFAULTS, "foo", value1);
598  storage2->Set(DEFAULTS, "bar", value2);
599  storage3->Set(DEFAULTS, "foo", value1);
600  storage4->Set(DEFAULTS, "bar", value2);
601
602  sync_processor_->ClearChanges();
603  storage1->Clear();
604  storage2->Clear();
605  storage3->Clear();
606  storage4->Clear();
607
608  EXPECT_EQ(
609      syncer::SyncChange::ACTION_DELETE,
610      sync_processor_->GetOnlyChange("s1", "foo").change_type());
611  EXPECT_EQ(
612      syncer::SyncChange::ACTION_DELETE,
613      sync_processor_->GetOnlyChange("s1", "bar").change_type());
614  EXPECT_EQ(
615      syncer::SyncChange::ACTION_DELETE,
616      sync_processor_->GetOnlyChange("s2", "foo").change_type());
617  EXPECT_EQ(
618      syncer::SyncChange::ACTION_DELETE,
619      sync_processor_->GetOnlyChange("s2", "bar").change_type());
620  EXPECT_EQ(
621      syncer::SyncChange::ACTION_DELETE,
622      sync_processor_->GetOnlyChange("s3", "foo").change_type());
623  EXPECT_EQ(
624      syncer::SyncChange::ACTION_DELETE,
625      sync_processor_->GetOnlyChange("s3", "bar").change_type());
626  EXPECT_EQ(
627      syncer::SyncChange::ACTION_DELETE,
628      sync_processor_->GetOnlyChange("s4", "foo").change_type());
629  EXPECT_EQ(
630      syncer::SyncChange::ACTION_DELETE,
631      sync_processor_->GetOnlyChange("s4", "bar").change_type());
632
633  GetSyncableService(model_type)->StopSyncing(model_type);
634}
635
636TEST_F(ExtensionSettingsSyncTest, ExtensionAndAppSettingsSyncSeparately) {
637  base::StringValue value1("fooValue");
638  base::ListValue value2;
639  value2.Append(new base::StringValue("barValue"));
640
641  // storage1 is an extension, storage2 is an app.
642  ValueStore* storage1 = AddExtensionAndGetStorage(
643      "s1", Manifest::TYPE_EXTENSION);
644  ValueStore* storage2 = AddExtensionAndGetStorage(
645      "s2", Manifest::TYPE_LEGACY_PACKAGED_APP);
646
647  storage1->Set(DEFAULTS, "foo", value1);
648  storage2->Set(DEFAULTS, "bar", value2);
649
650  std::map<std::string, SettingSyncDataList> extension_sync_data =
651      GetAllSyncData(syncer::EXTENSION_SETTINGS);
652  EXPECT_EQ(1u, extension_sync_data.size());
653  EXPECT_EQ(1u, extension_sync_data["s1"].size());
654  EXPECT_PRED_FORMAT2(ValuesEq, &value1, &extension_sync_data["s1"][0].value());
655
656  std::map<std::string, SettingSyncDataList> app_sync_data =
657      GetAllSyncData(syncer::APP_SETTINGS);
658  EXPECT_EQ(1u, app_sync_data.size());
659  EXPECT_EQ(1u, app_sync_data["s2"].size());
660  EXPECT_PRED_FORMAT2(ValuesEq, &value2, &app_sync_data["s2"][0].value());
661
662  // Stop each separately, there should be no changes either time.
663  syncer::SyncDataList sync_data;
664  sync_data.push_back(settings_sync_util::CreateData(
665      "s1", "foo", value1, syncer::EXTENSION_SETTINGS));
666
667  GetSyncableService(syncer::EXTENSION_SETTINGS)->MergeDataAndStartSyncing(
668      syncer::EXTENSION_SETTINGS,
669      sync_data,
670      sync_processor_wrapper_.PassAs<syncer::SyncChangeProcessor>(),
671      scoped_ptr<syncer::SyncErrorFactory>(new syncer::SyncErrorFactoryMock()));
672  GetSyncableService(syncer::EXTENSION_SETTINGS)->
673      StopSyncing(syncer::EXTENSION_SETTINGS);
674  EXPECT_EQ(0u, sync_processor_->changes().size());
675
676  sync_data.clear();
677  sync_data.push_back(settings_sync_util::CreateData(
678      "s2", "bar", value2, syncer::APP_SETTINGS));
679
680  scoped_ptr<syncer::SyncChangeProcessorWrapperForTest> app_settings_delegate_(
681      new syncer::SyncChangeProcessorWrapperForTest(sync_processor_.get()));
682  GetSyncableService(syncer::APP_SETTINGS)->MergeDataAndStartSyncing(
683      syncer::APP_SETTINGS,
684      sync_data,
685      app_settings_delegate_.PassAs<syncer::SyncChangeProcessor>(),
686      scoped_ptr<syncer::SyncErrorFactory>(new syncer::SyncErrorFactoryMock()));
687  GetSyncableService(syncer::APP_SETTINGS)->
688      StopSyncing(syncer::APP_SETTINGS);
689  EXPECT_EQ(0u, sync_processor_->changes().size());
690}
691
692TEST_F(ExtensionSettingsSyncTest, FailingStartSyncingDisablesSync) {
693  syncer::ModelType model_type = syncer::EXTENSION_SETTINGS;
694  Manifest::Type type = Manifest::TYPE_EXTENSION;
695
696  base::StringValue fooValue("fooValue");
697  base::StringValue barValue("barValue");
698
699  // There is a bit of a convoluted method to get storage areas that can fail;
700  // hand out TestingValueStore object then toggle them failing/succeeding
701  // as necessary.
702  TestingValueStoreFactory* testing_factory = new TestingValueStoreFactory();
703  storage_factory_->Reset(testing_factory);
704
705  ValueStore* good = AddExtensionAndGetStorage("good", type);
706  ValueStore* bad = AddExtensionAndGetStorage("bad", type);
707
708  // Make bad fail for incoming sync changes.
709  testing_factory->GetExisting("bad")->set_error_code(ValueStore::CORRUPTION);
710  {
711    syncer::SyncDataList sync_data;
712    sync_data.push_back(settings_sync_util::CreateData(
713          "good", "foo", fooValue, model_type));
714    sync_data.push_back(settings_sync_util::CreateData(
715          "bad", "foo", fooValue, model_type));
716    GetSyncableService(model_type)->MergeDataAndStartSyncing(
717        model_type,
718        sync_data,
719        sync_processor_wrapper_.PassAs<syncer::SyncChangeProcessor>(),
720        scoped_ptr<syncer::SyncErrorFactory>(
721            new syncer::SyncErrorFactoryMock()));
722  }
723  testing_factory->GetExisting("bad")->set_error_code(ValueStore::OK);
724
725  {
726    base::DictionaryValue dict;
727    dict.Set("foo", fooValue.DeepCopy());
728    EXPECT_PRED_FORMAT2(SettingsEq, dict, good->Get());
729  }
730  {
731    base::DictionaryValue dict;
732    EXPECT_PRED_FORMAT2(SettingsEq, dict, bad->Get());
733  }
734
735  // Changes made to good should be sent to sync, changes from bad shouldn't.
736  sync_processor_->ClearChanges();
737  good->Set(DEFAULTS, "bar", barValue);
738  bad->Set(DEFAULTS, "bar", barValue);
739
740  EXPECT_EQ(
741      syncer::SyncChange::ACTION_ADD,
742      sync_processor_->GetOnlyChange("good", "bar").change_type());
743  EXPECT_EQ(1u, sync_processor_->changes().size());
744
745  {
746    base::DictionaryValue dict;
747    dict.Set("foo", fooValue.DeepCopy());
748    dict.Set("bar", barValue.DeepCopy());
749    EXPECT_PRED_FORMAT2(SettingsEq, dict, good->Get());
750  }
751  {
752    base::DictionaryValue dict;
753    dict.Set("bar", barValue.DeepCopy());
754    EXPECT_PRED_FORMAT2(SettingsEq, dict, bad->Get());
755  }
756
757  // Changes received from sync should go to good but not bad (even when it's
758  // not failing).
759  {
760    syncer::SyncChangeList change_list;
761    change_list.push_back(settings_sync_util::CreateUpdate(
762          "good", "foo", barValue, model_type));
763    // (Sending UPDATE here even though it's adding, since that's what the state
764    // of sync is.  In any case, it won't work.)
765    change_list.push_back(settings_sync_util::CreateUpdate(
766          "bad", "foo", barValue, model_type));
767    GetSyncableService(model_type)->ProcessSyncChanges(FROM_HERE, change_list);
768  }
769
770  {
771    base::DictionaryValue dict;
772    dict.Set("foo", barValue.DeepCopy());
773    dict.Set("bar", barValue.DeepCopy());
774    EXPECT_PRED_FORMAT2(SettingsEq, dict, good->Get());
775  }
776  {
777    base::DictionaryValue dict;
778    dict.Set("bar", barValue.DeepCopy());
779    EXPECT_PRED_FORMAT2(SettingsEq, dict, bad->Get());
780  }
781
782  // Changes made to bad still shouldn't go to sync, even though it didn't fail
783  // last time.
784  sync_processor_->ClearChanges();
785  good->Set(DEFAULTS, "bar", fooValue);
786  bad->Set(DEFAULTS, "bar", fooValue);
787
788  EXPECT_EQ(
789      syncer::SyncChange::ACTION_UPDATE,
790      sync_processor_->GetOnlyChange("good", "bar").change_type());
791  EXPECT_EQ(1u, sync_processor_->changes().size());
792
793  {
794    base::DictionaryValue dict;
795    dict.Set("foo", barValue.DeepCopy());
796    dict.Set("bar", fooValue.DeepCopy());
797    EXPECT_PRED_FORMAT2(SettingsEq, dict, good->Get());
798  }
799  {
800    base::DictionaryValue dict;
801    dict.Set("bar", fooValue.DeepCopy());
802    EXPECT_PRED_FORMAT2(SettingsEq, dict, bad->Get());
803  }
804
805  // Failing ProcessSyncChanges shouldn't go to the storage.
806  testing_factory->GetExisting("bad")->set_error_code(ValueStore::CORRUPTION);
807  {
808    syncer::SyncChangeList change_list;
809    change_list.push_back(settings_sync_util::CreateUpdate(
810          "good", "foo", fooValue, model_type));
811    // (Ditto.)
812    change_list.push_back(settings_sync_util::CreateUpdate(
813          "bad", "foo", fooValue, model_type));
814    GetSyncableService(model_type)->ProcessSyncChanges(FROM_HERE, change_list);
815  }
816  testing_factory->GetExisting("bad")->set_error_code(ValueStore::OK);
817
818  {
819    base::DictionaryValue dict;
820    dict.Set("foo", fooValue.DeepCopy());
821    dict.Set("bar", fooValue.DeepCopy());
822    EXPECT_PRED_FORMAT2(SettingsEq, dict, good->Get());
823  }
824  {
825    base::DictionaryValue dict;
826    dict.Set("bar", fooValue.DeepCopy());
827    EXPECT_PRED_FORMAT2(SettingsEq, dict, bad->Get());
828  }
829
830  // Restarting sync should make bad start syncing again.
831  sync_processor_->ClearChanges();
832  GetSyncableService(model_type)->StopSyncing(model_type);
833  sync_processor_wrapper_.reset(
834      new syncer::SyncChangeProcessorWrapperForTest(sync_processor_.get()));
835  GetSyncableService(model_type)->MergeDataAndStartSyncing(
836      model_type,
837      syncer::SyncDataList(),
838      sync_processor_wrapper_.PassAs<syncer::SyncChangeProcessor>(),
839      scoped_ptr<syncer::SyncErrorFactory>(new syncer::SyncErrorFactoryMock()));
840
841  // Local settings will have been pushed to sync, since it's empty (in this
842  // test; presumably it wouldn't be live, since we've been getting changes).
843  EXPECT_EQ(
844      syncer::SyncChange::ACTION_ADD,
845      sync_processor_->GetOnlyChange("good", "foo").change_type());
846  EXPECT_EQ(
847      syncer::SyncChange::ACTION_ADD,
848      sync_processor_->GetOnlyChange("good", "bar").change_type());
849  EXPECT_EQ(
850      syncer::SyncChange::ACTION_ADD,
851      sync_processor_->GetOnlyChange("bad", "bar").change_type());
852  EXPECT_EQ(3u, sync_processor_->changes().size());
853
854  // Live local changes now get pushed, too.
855  sync_processor_->ClearChanges();
856  good->Set(DEFAULTS, "bar", barValue);
857  bad->Set(DEFAULTS, "bar", barValue);
858
859  EXPECT_EQ(
860      syncer::SyncChange::ACTION_UPDATE,
861      sync_processor_->GetOnlyChange("good", "bar").change_type());
862  EXPECT_EQ(
863      syncer::SyncChange::ACTION_UPDATE,
864      sync_processor_->GetOnlyChange("bad", "bar").change_type());
865  EXPECT_EQ(2u, sync_processor_->changes().size());
866
867  // And ProcessSyncChanges work, too.
868  {
869    syncer::SyncChangeList change_list;
870    change_list.push_back(settings_sync_util::CreateUpdate(
871          "good", "bar", fooValue, model_type));
872    change_list.push_back(settings_sync_util::CreateUpdate(
873          "bad", "bar", fooValue, model_type));
874    GetSyncableService(model_type)->ProcessSyncChanges(FROM_HERE, change_list);
875  }
876
877  {
878    base::DictionaryValue dict;
879    dict.Set("foo", fooValue.DeepCopy());
880    dict.Set("bar", fooValue.DeepCopy());
881    EXPECT_PRED_FORMAT2(SettingsEq, dict, good->Get());
882  }
883  {
884    base::DictionaryValue dict;
885    dict.Set("bar", fooValue.DeepCopy());
886    EXPECT_PRED_FORMAT2(SettingsEq, dict, bad->Get());
887  }
888}
889
890TEST_F(ExtensionSettingsSyncTest, FailingProcessChangesDisablesSync) {
891  // The test above tests a failing ProcessSyncChanges too, but here test with
892  // an initially passing MergeDataAndStartSyncing.
893  syncer::ModelType model_type = syncer::APP_SETTINGS;
894  Manifest::Type type = Manifest::TYPE_LEGACY_PACKAGED_APP;
895
896  base::StringValue fooValue("fooValue");
897  base::StringValue barValue("barValue");
898
899  TestingValueStoreFactory* testing_factory = new TestingValueStoreFactory();
900  storage_factory_->Reset(testing_factory);
901
902  ValueStore* good = AddExtensionAndGetStorage("good", type);
903  ValueStore* bad = AddExtensionAndGetStorage("bad", type);
904
905  // Unlike before, initially succeeding MergeDataAndStartSyncing.
906  {
907    syncer::SyncDataList sync_data;
908    sync_data.push_back(settings_sync_util::CreateData(
909          "good", "foo", fooValue, model_type));
910    sync_data.push_back(settings_sync_util::CreateData(
911          "bad", "foo", fooValue, model_type));
912    GetSyncableService(model_type)->MergeDataAndStartSyncing(
913        model_type,
914        sync_data,
915        sync_processor_wrapper_.PassAs<syncer::SyncChangeProcessor>(),
916        scoped_ptr<syncer::SyncErrorFactory>(
917            new syncer::SyncErrorFactoryMock()));
918  }
919
920  EXPECT_EQ(0u, sync_processor_->changes().size());
921
922  {
923    base::DictionaryValue dict;
924    dict.Set("foo", fooValue.DeepCopy());
925    EXPECT_PRED_FORMAT2(SettingsEq, dict, good->Get());
926  }
927  {
928    base::DictionaryValue dict;
929    dict.Set("foo", fooValue.DeepCopy());
930    EXPECT_PRED_FORMAT2(SettingsEq, dict, bad->Get());
931  }
932
933  // Now fail ProcessSyncChanges for bad.
934  testing_factory->GetExisting("bad")->set_error_code(ValueStore::CORRUPTION);
935  {
936    syncer::SyncChangeList change_list;
937    change_list.push_back(settings_sync_util::CreateAdd(
938          "good", "bar", barValue, model_type));
939    change_list.push_back(settings_sync_util::CreateAdd(
940          "bad", "bar", barValue, model_type));
941    GetSyncableService(model_type)->ProcessSyncChanges(FROM_HERE, change_list);
942  }
943  testing_factory->GetExisting("bad")->set_error_code(ValueStore::OK);
944
945  {
946    base::DictionaryValue dict;
947    dict.Set("foo", fooValue.DeepCopy());
948    dict.Set("bar", barValue.DeepCopy());
949    EXPECT_PRED_FORMAT2(SettingsEq, dict, good->Get());
950  }
951  {
952    base::DictionaryValue dict;
953    dict.Set("foo", fooValue.DeepCopy());
954    EXPECT_PRED_FORMAT2(SettingsEq, dict, bad->Get());
955  }
956
957  // No more changes sent to sync for bad.
958  sync_processor_->ClearChanges();
959  good->Set(DEFAULTS, "foo", barValue);
960  bad->Set(DEFAULTS, "foo", barValue);
961
962  EXPECT_EQ(
963      syncer::SyncChange::ACTION_UPDATE,
964      sync_processor_->GetOnlyChange("good", "foo").change_type());
965  EXPECT_EQ(1u, sync_processor_->changes().size());
966
967  // No more changes received from sync should go to bad.
968  {
969    syncer::SyncChangeList change_list;
970    change_list.push_back(settings_sync_util::CreateAdd(
971          "good", "foo", fooValue, model_type));
972    change_list.push_back(settings_sync_util::CreateAdd(
973          "bad", "foo", fooValue, model_type));
974    GetSyncableService(model_type)->ProcessSyncChanges(FROM_HERE, change_list);
975  }
976
977  {
978    base::DictionaryValue dict;
979    dict.Set("foo", fooValue.DeepCopy());
980    dict.Set("bar", barValue.DeepCopy());
981    EXPECT_PRED_FORMAT2(SettingsEq, dict, good->Get());
982  }
983  {
984    base::DictionaryValue dict;
985    dict.Set("foo", barValue.DeepCopy());
986    EXPECT_PRED_FORMAT2(SettingsEq, dict, bad->Get());
987  }
988}
989
990TEST_F(ExtensionSettingsSyncTest, FailingGetAllSyncDataDoesntStopSync) {
991  syncer::ModelType model_type = syncer::EXTENSION_SETTINGS;
992  Manifest::Type type = Manifest::TYPE_EXTENSION;
993
994  base::StringValue fooValue("fooValue");
995  base::StringValue barValue("barValue");
996
997  TestingValueStoreFactory* testing_factory = new TestingValueStoreFactory();
998  storage_factory_->Reset(testing_factory);
999
1000  ValueStore* good = AddExtensionAndGetStorage("good", type);
1001  ValueStore* bad = AddExtensionAndGetStorage("bad", type);
1002
1003  good->Set(DEFAULTS, "foo", fooValue);
1004  bad->Set(DEFAULTS, "foo", fooValue);
1005
1006  // Even though bad will fail to get all sync data, sync data should still
1007  // include that from good.
1008  testing_factory->GetExisting("bad")->set_error_code(ValueStore::CORRUPTION);
1009  {
1010    syncer::SyncDataList all_sync_data =
1011        GetSyncableService(model_type)->GetAllSyncData(model_type);
1012    EXPECT_EQ(1u, all_sync_data.size());
1013    EXPECT_EQ("good/foo", all_sync_data[0].GetTag());
1014  }
1015  testing_factory->GetExisting("bad")->set_error_code(ValueStore::OK);
1016
1017  // Sync shouldn't be disabled for good (nor bad -- but this is unimportant).
1018  GetSyncableService(model_type)->MergeDataAndStartSyncing(
1019      model_type,
1020      syncer::SyncDataList(),
1021      sync_processor_wrapper_.PassAs<syncer::SyncChangeProcessor>(),
1022      scoped_ptr<syncer::SyncErrorFactory>(new syncer::SyncErrorFactoryMock()));
1023
1024  EXPECT_EQ(
1025      syncer::SyncChange::ACTION_ADD,
1026      sync_processor_->GetOnlyChange("good", "foo").change_type());
1027  EXPECT_EQ(
1028      syncer::SyncChange::ACTION_ADD,
1029      sync_processor_->GetOnlyChange("bad", "foo").change_type());
1030  EXPECT_EQ(2u, sync_processor_->changes().size());
1031
1032  sync_processor_->ClearChanges();
1033  good->Set(DEFAULTS, "bar", barValue);
1034  bad->Set(DEFAULTS, "bar", barValue);
1035
1036  EXPECT_EQ(
1037      syncer::SyncChange::ACTION_ADD,
1038      sync_processor_->GetOnlyChange("good", "bar").change_type());
1039  EXPECT_EQ(
1040      syncer::SyncChange::ACTION_ADD,
1041      sync_processor_->GetOnlyChange("bad", "bar").change_type());
1042  EXPECT_EQ(2u, sync_processor_->changes().size());
1043}
1044
1045TEST_F(ExtensionSettingsSyncTest, FailureToReadChangesToPushDisablesSync) {
1046  syncer::ModelType model_type = syncer::APP_SETTINGS;
1047  Manifest::Type type = Manifest::TYPE_LEGACY_PACKAGED_APP;
1048
1049  base::StringValue fooValue("fooValue");
1050  base::StringValue barValue("barValue");
1051
1052  TestingValueStoreFactory* testing_factory = new TestingValueStoreFactory();
1053  storage_factory_->Reset(testing_factory);
1054
1055  ValueStore* good = AddExtensionAndGetStorage("good", type);
1056  ValueStore* bad = AddExtensionAndGetStorage("bad", type);
1057
1058  good->Set(DEFAULTS, "foo", fooValue);
1059  bad->Set(DEFAULTS, "foo", fooValue);
1060
1061  // good will successfully push foo:fooValue to sync, but bad will fail to
1062  // get them so won't.
1063  testing_factory->GetExisting("bad")->set_error_code(ValueStore::CORRUPTION);
1064  GetSyncableService(model_type)->MergeDataAndStartSyncing(
1065      model_type,
1066      syncer::SyncDataList(),
1067      sync_processor_wrapper_.PassAs<syncer::SyncChangeProcessor>(),
1068      scoped_ptr<syncer::SyncErrorFactory>(new syncer::SyncErrorFactoryMock()));
1069  testing_factory->GetExisting("bad")->set_error_code(ValueStore::OK);
1070
1071  EXPECT_EQ(
1072      syncer::SyncChange::ACTION_ADD,
1073      sync_processor_->GetOnlyChange("good", "foo").change_type());
1074  EXPECT_EQ(1u, sync_processor_->changes().size());
1075
1076  // bad should now be disabled for sync.
1077  sync_processor_->ClearChanges();
1078  good->Set(DEFAULTS, "bar", barValue);
1079  bad->Set(DEFAULTS, "bar", barValue);
1080
1081  EXPECT_EQ(
1082      syncer::SyncChange::ACTION_ADD,
1083      sync_processor_->GetOnlyChange("good", "bar").change_type());
1084  EXPECT_EQ(1u, sync_processor_->changes().size());
1085
1086  {
1087    syncer::SyncChangeList change_list;
1088    change_list.push_back(settings_sync_util::CreateUpdate(
1089          "good", "foo", barValue, model_type));
1090    // (Sending ADD here even though it's updating, since that's what the state
1091    // of sync is.  In any case, it won't work.)
1092    change_list.push_back(settings_sync_util::CreateAdd(
1093          "bad", "foo", barValue, model_type));
1094    GetSyncableService(model_type)->ProcessSyncChanges(FROM_HERE, change_list);
1095  }
1096
1097  {
1098    base::DictionaryValue dict;
1099    dict.Set("foo", barValue.DeepCopy());
1100    dict.Set("bar", barValue.DeepCopy());
1101    EXPECT_PRED_FORMAT2(SettingsEq, dict, good->Get());
1102  }
1103  {
1104    base::DictionaryValue dict;
1105    dict.Set("foo", fooValue.DeepCopy());
1106    dict.Set("bar", barValue.DeepCopy());
1107    EXPECT_PRED_FORMAT2(SettingsEq, dict, bad->Get());
1108  }
1109
1110  // Re-enabling sync without failing should cause the local changes from bad
1111  // to be pushed to sync successfully, as should future changes to bad.
1112  sync_processor_->ClearChanges();
1113  GetSyncableService(model_type)->StopSyncing(model_type);
1114  sync_processor_wrapper_.reset(
1115      new syncer::SyncChangeProcessorWrapperForTest(sync_processor_.get()));
1116  GetSyncableService(model_type)->MergeDataAndStartSyncing(
1117      model_type,
1118      syncer::SyncDataList(),
1119      sync_processor_wrapper_.PassAs<syncer::SyncChangeProcessor>(),
1120      scoped_ptr<syncer::SyncErrorFactory>(new syncer::SyncErrorFactoryMock()));
1121
1122  EXPECT_EQ(
1123      syncer::SyncChange::ACTION_ADD,
1124      sync_processor_->GetOnlyChange("good", "foo").change_type());
1125  EXPECT_EQ(
1126      syncer::SyncChange::ACTION_ADD,
1127      sync_processor_->GetOnlyChange("good", "bar").change_type());
1128  EXPECT_EQ(
1129      syncer::SyncChange::ACTION_ADD,
1130      sync_processor_->GetOnlyChange("bad", "foo").change_type());
1131  EXPECT_EQ(
1132      syncer::SyncChange::ACTION_ADD,
1133      sync_processor_->GetOnlyChange("bad", "bar").change_type());
1134  EXPECT_EQ(4u, sync_processor_->changes().size());
1135
1136  sync_processor_->ClearChanges();
1137  good->Set(DEFAULTS, "bar", fooValue);
1138  bad->Set(DEFAULTS, "bar", fooValue);
1139
1140  EXPECT_EQ(
1141      syncer::SyncChange::ACTION_UPDATE,
1142      sync_processor_->GetOnlyChange("good", "bar").change_type());
1143  EXPECT_EQ(
1144      syncer::SyncChange::ACTION_UPDATE,
1145      sync_processor_->GetOnlyChange("good", "bar").change_type());
1146  EXPECT_EQ(2u, sync_processor_->changes().size());
1147}
1148
1149TEST_F(ExtensionSettingsSyncTest, FailureToPushLocalStateDisablesSync) {
1150  syncer::ModelType model_type = syncer::EXTENSION_SETTINGS;
1151  Manifest::Type type = Manifest::TYPE_EXTENSION;
1152
1153  base::StringValue fooValue("fooValue");
1154  base::StringValue barValue("barValue");
1155
1156  TestingValueStoreFactory* testing_factory = new TestingValueStoreFactory();
1157  storage_factory_->Reset(testing_factory);
1158
1159  ValueStore* good = AddExtensionAndGetStorage("good", type);
1160  ValueStore* bad = AddExtensionAndGetStorage("bad", type);
1161
1162  // Only set bad; setting good will cause it to fail below.
1163  bad->Set(DEFAULTS, "foo", fooValue);
1164
1165  sync_processor_->set_fail_all_requests(true);
1166  GetSyncableService(model_type)->MergeDataAndStartSyncing(
1167      model_type,
1168      syncer::SyncDataList(),
1169      sync_processor_wrapper_.PassAs<syncer::SyncChangeProcessor>(),
1170      scoped_ptr<syncer::SyncErrorFactory>(new syncer::SyncErrorFactoryMock()));
1171  sync_processor_->set_fail_all_requests(false);
1172
1173  // Changes from good will be send to sync, changes from bad won't.
1174  sync_processor_->ClearChanges();
1175  good->Set(DEFAULTS, "foo", barValue);
1176  bad->Set(DEFAULTS, "foo", barValue);
1177
1178  EXPECT_EQ(
1179      syncer::SyncChange::ACTION_ADD,
1180      sync_processor_->GetOnlyChange("good", "foo").change_type());
1181  EXPECT_EQ(1u, sync_processor_->changes().size());
1182
1183  // Changes from sync will be sent to good, not to bad.
1184  {
1185    syncer::SyncChangeList change_list;
1186    change_list.push_back(settings_sync_util::CreateAdd(
1187          "good", "bar", barValue, model_type));
1188    change_list.push_back(settings_sync_util::CreateAdd(
1189          "bad", "bar", barValue, model_type));
1190    GetSyncableService(model_type)->ProcessSyncChanges(FROM_HERE, change_list);
1191  }
1192
1193  {
1194    base::DictionaryValue dict;
1195    dict.Set("foo", barValue.DeepCopy());
1196    dict.Set("bar", barValue.DeepCopy());
1197    EXPECT_PRED_FORMAT2(SettingsEq, dict, good->Get());
1198  }
1199  {
1200    base::DictionaryValue dict;
1201    dict.Set("foo", barValue.DeepCopy());
1202    EXPECT_PRED_FORMAT2(SettingsEq, dict, bad->Get());
1203  }
1204
1205  // Restarting sync makes everything work again.
1206  sync_processor_->ClearChanges();
1207  GetSyncableService(model_type)->StopSyncing(model_type);
1208  sync_processor_wrapper_.reset(
1209      new syncer::SyncChangeProcessorWrapperForTest(sync_processor_.get()));
1210  GetSyncableService(model_type)->MergeDataAndStartSyncing(
1211      model_type,
1212      syncer::SyncDataList(),
1213      sync_processor_wrapper_.PassAs<syncer::SyncChangeProcessor>(),
1214      scoped_ptr<syncer::SyncErrorFactory>(new syncer::SyncErrorFactoryMock()));
1215
1216  EXPECT_EQ(
1217      syncer::SyncChange::ACTION_ADD,
1218      sync_processor_->GetOnlyChange("good", "foo").change_type());
1219  EXPECT_EQ(
1220      syncer::SyncChange::ACTION_ADD,
1221      sync_processor_->GetOnlyChange("good", "bar").change_type());
1222  EXPECT_EQ(
1223      syncer::SyncChange::ACTION_ADD,
1224      sync_processor_->GetOnlyChange("bad", "foo").change_type());
1225  EXPECT_EQ(3u, sync_processor_->changes().size());
1226
1227  sync_processor_->ClearChanges();
1228  good->Set(DEFAULTS, "foo", fooValue);
1229  bad->Set(DEFAULTS, "foo", fooValue);
1230
1231  EXPECT_EQ(
1232      syncer::SyncChange::ACTION_UPDATE,
1233      sync_processor_->GetOnlyChange("good", "foo").change_type());
1234  EXPECT_EQ(
1235      syncer::SyncChange::ACTION_UPDATE,
1236      sync_processor_->GetOnlyChange("good", "foo").change_type());
1237  EXPECT_EQ(2u, sync_processor_->changes().size());
1238}
1239
1240TEST_F(ExtensionSettingsSyncTest, FailureToPushLocalChangeDisablesSync) {
1241  syncer::ModelType model_type = syncer::EXTENSION_SETTINGS;
1242  Manifest::Type type = Manifest::TYPE_EXTENSION;
1243
1244  base::StringValue fooValue("fooValue");
1245  base::StringValue barValue("barValue");
1246
1247  TestingValueStoreFactory* testing_factory = new TestingValueStoreFactory();
1248  storage_factory_->Reset(testing_factory);
1249
1250  ValueStore* good = AddExtensionAndGetStorage("good", type);
1251  ValueStore* bad = AddExtensionAndGetStorage("bad", type);
1252
1253  GetSyncableService(model_type)->MergeDataAndStartSyncing(
1254      model_type,
1255      syncer::SyncDataList(),
1256      sync_processor_wrapper_.PassAs<syncer::SyncChangeProcessor>(),
1257      scoped_ptr<syncer::SyncErrorFactory>(new syncer::SyncErrorFactoryMock()));
1258
1259  // bad will fail to send changes.
1260  good->Set(DEFAULTS, "foo", fooValue);
1261  sync_processor_->set_fail_all_requests(true);
1262  bad->Set(DEFAULTS, "foo", fooValue);
1263  sync_processor_->set_fail_all_requests(false);
1264
1265  EXPECT_EQ(
1266      syncer::SyncChange::ACTION_ADD,
1267      sync_processor_->GetOnlyChange("good", "foo").change_type());
1268  EXPECT_EQ(1u, sync_processor_->changes().size());
1269
1270  // No further changes should be sent from bad.
1271  sync_processor_->ClearChanges();
1272  good->Set(DEFAULTS, "foo", barValue);
1273  bad->Set(DEFAULTS, "foo", barValue);
1274
1275  EXPECT_EQ(
1276      syncer::SyncChange::ACTION_UPDATE,
1277      sync_processor_->GetOnlyChange("good", "foo").change_type());
1278  EXPECT_EQ(1u, sync_processor_->changes().size());
1279
1280  // Changes from sync will be sent to good, not to bad.
1281  {
1282    syncer::SyncChangeList change_list;
1283    change_list.push_back(settings_sync_util::CreateAdd(
1284          "good", "bar", barValue, model_type));
1285    change_list.push_back(settings_sync_util::CreateAdd(
1286          "bad", "bar", barValue, model_type));
1287    GetSyncableService(model_type)->ProcessSyncChanges(FROM_HERE, change_list);
1288  }
1289
1290  {
1291    base::DictionaryValue dict;
1292    dict.Set("foo", barValue.DeepCopy());
1293    dict.Set("bar", barValue.DeepCopy());
1294    EXPECT_PRED_FORMAT2(SettingsEq, dict, good->Get());
1295  }
1296  {
1297    base::DictionaryValue dict;
1298    dict.Set("foo", barValue.DeepCopy());
1299    EXPECT_PRED_FORMAT2(SettingsEq, dict, bad->Get());
1300  }
1301
1302  // Restarting sync makes everything work again.
1303  sync_processor_->ClearChanges();
1304  GetSyncableService(model_type)->StopSyncing(model_type);
1305  sync_processor_wrapper_.reset(
1306      new syncer::SyncChangeProcessorWrapperForTest(sync_processor_.get()));
1307  GetSyncableService(model_type)->MergeDataAndStartSyncing(
1308      model_type,
1309      syncer::SyncDataList(),
1310      sync_processor_wrapper_.PassAs<syncer::SyncChangeProcessor>(),
1311      scoped_ptr<syncer::SyncErrorFactory>(new syncer::SyncErrorFactoryMock()));
1312
1313  EXPECT_EQ(
1314      syncer::SyncChange::ACTION_ADD,
1315      sync_processor_->GetOnlyChange("good", "foo").change_type());
1316  EXPECT_EQ(
1317      syncer::SyncChange::ACTION_ADD,
1318      sync_processor_->GetOnlyChange("good", "bar").change_type());
1319  EXPECT_EQ(
1320      syncer::SyncChange::ACTION_ADD,
1321      sync_processor_->GetOnlyChange("bad", "foo").change_type());
1322  EXPECT_EQ(3u, sync_processor_->changes().size());
1323
1324  sync_processor_->ClearChanges();
1325  good->Set(DEFAULTS, "foo", fooValue);
1326  bad->Set(DEFAULTS, "foo", fooValue);
1327
1328  EXPECT_EQ(
1329      syncer::SyncChange::ACTION_UPDATE,
1330      sync_processor_->GetOnlyChange("good", "foo").change_type());
1331  EXPECT_EQ(
1332      syncer::SyncChange::ACTION_UPDATE,
1333      sync_processor_->GetOnlyChange("good", "foo").change_type());
1334  EXPECT_EQ(2u, sync_processor_->changes().size());
1335}
1336
1337TEST_F(ExtensionSettingsSyncTest,
1338       LargeOutgoingChangeRejectedButIncomingAccepted) {
1339  syncer::ModelType model_type = syncer::APP_SETTINGS;
1340  Manifest::Type type = Manifest::TYPE_LEGACY_PACKAGED_APP;
1341
1342  // This value should be larger than the limit in sync_storage_backend.cc.
1343  std::string string_5k;
1344  for (size_t i = 0; i < 5000; ++i) {
1345    string_5k.append("a");
1346  }
1347  base::StringValue large_value(string_5k);
1348
1349  GetSyncableService(model_type)->MergeDataAndStartSyncing(
1350      model_type,
1351      syncer::SyncDataList(),
1352      sync_processor_wrapper_.PassAs<syncer::SyncChangeProcessor>(),
1353      scoped_ptr<syncer::SyncErrorFactory>(new syncer::SyncErrorFactoryMock()));
1354
1355  // Large local change rejected and doesn't get sent out.
1356  ValueStore* storage1 = AddExtensionAndGetStorage("s1", type);
1357  EXPECT_TRUE(storage1->Set(DEFAULTS, "large_value", large_value)->HasError());
1358  EXPECT_EQ(0u, sync_processor_->changes().size());
1359
1360  // Large incoming change should still get accepted.
1361  ValueStore* storage2 = AddExtensionAndGetStorage("s2", type);
1362  {
1363    syncer::SyncChangeList change_list;
1364    change_list.push_back(settings_sync_util::CreateAdd(
1365          "s1", "large_value", large_value, model_type));
1366    change_list.push_back(settings_sync_util::CreateAdd(
1367          "s2", "large_value", large_value, model_type));
1368    GetSyncableService(model_type)->ProcessSyncChanges(FROM_HERE, change_list);
1369  }
1370  {
1371    base::DictionaryValue expected;
1372    expected.Set("large_value", large_value.DeepCopy());
1373    EXPECT_PRED_FORMAT2(SettingsEq, expected, storage1->Get());
1374    EXPECT_PRED_FORMAT2(SettingsEq, expected, storage2->Get());
1375  }
1376
1377  GetSyncableService(model_type)->StopSyncing(model_type);
1378}
1379
1380TEST_F(ExtensionSettingsSyncTest, Dots) {
1381  syncer::ModelType model_type = syncer::EXTENSION_SETTINGS;
1382  Manifest::Type type = Manifest::TYPE_EXTENSION;
1383
1384  ValueStore* storage = AddExtensionAndGetStorage("ext", type);
1385
1386  {
1387    syncer::SyncDataList sync_data_list;
1388    scoped_ptr<base::Value> string_value(new base::StringValue("value"));
1389    sync_data_list.push_back(settings_sync_util::CreateData(
1390        "ext", "key.with.dot", *string_value, model_type));
1391
1392    GetSyncableService(model_type)->MergeDataAndStartSyncing(
1393        model_type,
1394        sync_data_list,
1395        sync_processor_wrapper_.PassAs<syncer::SyncChangeProcessor>(),
1396        scoped_ptr<syncer::SyncErrorFactory>(
1397            new syncer::SyncErrorFactoryMock()));
1398  }
1399
1400  // Test dots in keys that come from sync.
1401  {
1402    ValueStore::ReadResult data = storage->Get();
1403    ASSERT_FALSE(data->HasError());
1404
1405    base::DictionaryValue expected_data;
1406    expected_data.SetWithoutPathExpansion(
1407        "key.with.dot",
1408        new base::StringValue("value"));
1409    EXPECT_TRUE(base::Value::Equals(&expected_data, &data->settings()));
1410  }
1411
1412  // Test dots in keys going to sync.
1413  {
1414    scoped_ptr<base::Value> string_value(new base::StringValue("spot"));
1415    storage->Set(DEFAULTS, "key.with.spot", *string_value);
1416
1417    ASSERT_EQ(1u, sync_processor_->changes().size());
1418    SettingSyncData sync_data = sync_processor_->changes()[0];
1419    EXPECT_EQ(syncer::SyncChange::ACTION_ADD, sync_data.change_type());
1420    EXPECT_EQ("ext", sync_data.extension_id());
1421    EXPECT_EQ("key.with.spot", sync_data.key());
1422    EXPECT_TRUE(sync_data.value().Equals(string_value.get()));
1423  }
1424}
1425
1426}  // namespace extensions
1427