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