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