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.
6 #include "base/files/scoped_temp_dir.h"
7 #include "base/json/json_reader.h"
8 #include "base/json/json_writer.h"
9 #include "base/memory/scoped_ptr.h"
10 #include "base/message_loop/message_loop.h"
11 #include "base/strings/stringprintf.h"
12 #include "chrome/browser/extensions/api/storage/settings_sync_util.h"
13 #include "chrome/browser/extensions/api/storage/sync_value_store_cache.h"
14 #include "chrome/browser/extensions/api/storage/syncable_settings_storage.h"
15 #include "chrome/test/base/testing_profile.h"
16 #include "content/public/test/test_browser_thread.h"
17 #include "extensions/browser/api/storage/leveldb_settings_storage_factory.h"
18 #include "extensions/browser/api/storage/settings_storage_factory.h"
19 #include "extensions/browser/api/storage/settings_test_util.h"
20 #include "extensions/browser/api/storage/storage_frontend.h"
21 #include "extensions/browser/extension_system.h"
22 #include "extensions/browser/mock_extension_system.h"
23 #include "extensions/browser/value_store/testing_value_store.h"
24 #include "extensions/common/manifest.h"
25 #include "sync/api/sync_change_processor.h"
26 #include "sync/api/sync_change_processor_wrapper_for_test.h"
27 #include "sync/api/sync_error_factory.h"
28 #include "sync/api/sync_error_factory_mock.h"
29 #include "testing/gtest/include/gtest/gtest.h"
31 using base::DictionaryValue
;
32 using base::ListValue
;
34 using content::BrowserThread
;
36 namespace extensions
{
38 namespace util
= settings_test_util
;
42 // To save typing ValueStore::DEFAULTS everywhere.
43 const ValueStore::WriteOptions DEFAULTS
= ValueStore::DEFAULTS
;
45 // Gets the pretty-printed JSON for a value.
46 static std::string
GetJson(const base::Value
& value
) {
48 base::JSONWriter::WriteWithOptions(&value
,
49 base::JSONWriter::OPTIONS_PRETTY_PRINT
,
54 // Returns whether two Values are equal.
55 testing::AssertionResult
ValuesEq(
56 const char* _1
, const char* _2
,
57 const base::Value
* expected
,
58 const base::Value
* actual
) {
59 if (expected
== actual
) {
60 return testing::AssertionSuccess();
62 if (!expected
&& actual
) {
63 return testing::AssertionFailure() <<
64 "Expected NULL, actual: " << GetJson(*actual
);
66 if (expected
&& !actual
) {
67 return testing::AssertionFailure() <<
68 "Expected: " << GetJson(*expected
) << ", actual NULL";
70 if (!expected
->Equals(actual
)) {
71 return testing::AssertionFailure() <<
72 "Expected: " << GetJson(*expected
) << ", actual: " << GetJson(*actual
);
74 return testing::AssertionSuccess();
77 // Returns whether the result of a storage operation is an expected value.
78 // Logs when different.
79 testing::AssertionResult
SettingsEq(
80 const char* _1
, const char* _2
,
81 const base::DictionaryValue
& expected
,
82 ValueStore::ReadResult actual
) {
83 if (actual
->HasError()) {
84 return testing::AssertionFailure() <<
85 "Expected: " << expected
<<
86 ", actual has error: " << actual
->error().message
;
88 return ValuesEq(_1
, _2
, &expected
, &actual
->settings());
91 // SyncChangeProcessor which just records the changes made, accessed after
92 // being converted to the more useful SettingSyncData via changes().
93 class MockSyncChangeProcessor
: public syncer::SyncChangeProcessor
{
95 MockSyncChangeProcessor() : fail_all_requests_(false) {}
97 // syncer::SyncChangeProcessor implementation.
98 syncer::SyncError
ProcessSyncChanges(
99 const tracked_objects::Location
& from_here
,
100 const syncer::SyncChangeList
& change_list
) override
{
101 if (fail_all_requests_
) {
102 return syncer::SyncError(
104 syncer::SyncError::DATATYPE_ERROR
,
105 "MockSyncChangeProcessor: configured to fail",
106 change_list
[0].sync_data().GetDataType());
108 for (syncer::SyncChangeList::const_iterator it
= change_list
.begin();
109 it
!= change_list
.end(); ++it
) {
110 changes_
.push_back(SettingSyncData(*it
));
112 return syncer::SyncError();
115 syncer::SyncDataList
GetAllSyncData(syncer::ModelType type
) const override
{
116 return syncer::SyncDataList();
121 const SettingSyncDataList
& changes() { return changes_
; }
123 void ClearChanges() {
127 void set_fail_all_requests(bool fail_all_requests
) {
128 fail_all_requests_
= fail_all_requests
;
131 // Returns the only change for a given extension setting. If there is not
132 // exactly 1 change for that key, a test assertion will fail.
133 SettingSyncData
GetOnlyChange(
134 const std::string
& extension_id
, const std::string
& key
) {
135 SettingSyncDataList matching_changes
;
136 for (SettingSyncDataList::iterator it
= changes_
.begin();
137 it
!= changes_
.end(); ++it
) {
138 if (it
->extension_id() == extension_id
&& it
->key() == key
) {
139 matching_changes
.push_back(*it
);
142 if (matching_changes
.empty()) {
143 ADD_FAILURE() << "No matching changes for " << extension_id
<< "/" <<
144 key
<< " (out of " << changes_
.size() << ")";
145 return SettingSyncData(syncer::SyncChange::ACTION_INVALID
,
148 scoped_ptr
<base::Value
>(
149 new base::DictionaryValue()));
151 if (matching_changes
.size() != 1u) {
152 ADD_FAILURE() << matching_changes
.size() << " matching changes for " <<
153 extension_id
<< "/" << key
<< " (out of " << changes_
.size() << ")";
155 return matching_changes
[0];
159 SettingSyncDataList changes_
;
160 bool fail_all_requests_
;
163 // SettingsStorageFactory which always returns TestingValueStore objects,
164 // and allows individually created objects to be returned.
165 class TestingValueStoreFactory
: public SettingsStorageFactory
{
167 TestingValueStore
* GetExisting(const std::string
& extension_id
) {
168 DCHECK(created_
.count(extension_id
));
169 return created_
[extension_id
];
172 // SettingsStorageFactory implementation.
173 ValueStore
* Create(const base::FilePath
& base_path
,
174 const std::string
& extension_id
) override
{
175 TestingValueStore
* new_storage
= new TestingValueStore();
176 DCHECK(!created_
.count(extension_id
));
177 created_
[extension_id
] = new_storage
;
181 // Testing value stores don't actually create a real database. Don't delete
183 void DeleteDatabaseIfExists(const base::FilePath
& base_path
,
184 const std::string
& extension_id
) override
{}
187 // SettingsStorageFactory is refcounted.
188 ~TestingValueStoreFactory() override
{}
190 // None of these storage areas are owned by this factory, so care must be
191 // taken when calling GetExisting.
192 std::map
<std::string
, TestingValueStore
*> created_
;
197 class ExtensionSettingsSyncTest
: public testing::Test
{
199 ExtensionSettingsSyncTest()
200 : ui_thread_(BrowserThread::UI
, base::MessageLoop::current()),
201 file_thread_(BrowserThread::FILE, base::MessageLoop::current()),
202 storage_factory_(new util::ScopedSettingsStorageFactory()),
203 sync_processor_(new MockSyncChangeProcessor
),
204 sync_processor_wrapper_(new syncer::SyncChangeProcessorWrapperForTest(
205 sync_processor_
.get())) {}
207 void SetUp() override
{
208 ASSERT_TRUE(temp_dir_
.CreateUniqueTempDir());
209 profile_
.reset(new TestingProfile(temp_dir_
.path()));
210 storage_factory_
->Reset(new LeveldbSettingsStorageFactory());
212 StorageFrontend::CreateForTesting(storage_factory_
, profile_
.get()));
214 ExtensionsBrowserClient::Get()
215 ->GetExtensionSystemFactory()
216 ->SetTestingFactoryAndUse(
217 profile_
.get(), &util::MockExtensionSystemWithEventRouter::Build
);
220 void TearDown() override
{
223 // Execute any pending deletion tasks.
224 message_loop_
.RunUntilIdle();
228 // Adds a record of an extension or app to the extension service, then returns
230 ValueStore
* AddExtensionAndGetStorage(
231 const std::string
& id
, Manifest::Type type
) {
232 scoped_refptr
<const Extension
> extension
=
233 util::AddExtensionWithId(profile_
.get(), id
, type
);
234 return util::GetStorage(extension
, frontend_
.get());
237 // Gets the syncer::SyncableService for the given sync type.
238 syncer::SyncableService
* GetSyncableService(syncer::ModelType model_type
) {
239 base::MessageLoop::current()->RunUntilIdle();
240 SyncValueStoreCache
* sync_cache
= static_cast<SyncValueStoreCache
*>(
241 frontend_
->GetValueStoreCache(settings_namespace::SYNC
));
242 return sync_cache
->GetSyncableService(model_type
);
245 // Gets all the sync data from the SyncableService for a sync type as a map
246 // from extension id to its sync data.
247 std::map
<std::string
, SettingSyncDataList
> GetAllSyncData(
248 syncer::ModelType model_type
) {
249 syncer::SyncDataList as_list
=
250 GetSyncableService(model_type
)->GetAllSyncData(model_type
);
251 std::map
<std::string
, SettingSyncDataList
> as_map
;
252 for (syncer::SyncDataList::iterator it
= as_list
.begin();
253 it
!= as_list
.end(); ++it
) {
254 SettingSyncData
sync_data(*it
);
255 as_map
[sync_data
.extension_id()].push_back(sync_data
);
260 // Need these so that the DCHECKs for running on FILE or UI threads pass.
261 base::MessageLoop message_loop_
;
262 content::TestBrowserThread ui_thread_
;
263 content::TestBrowserThread file_thread_
;
265 base::ScopedTempDir temp_dir_
;
266 scoped_ptr
<TestingProfile
> profile_
;
267 scoped_ptr
<StorageFrontend
> frontend_
;
268 scoped_refptr
<util::ScopedSettingsStorageFactory
> storage_factory_
;
269 scoped_ptr
<MockSyncChangeProcessor
> sync_processor_
;
270 scoped_ptr
<syncer::SyncChangeProcessorWrapperForTest
> sync_processor_wrapper_
;
273 // Get a semblance of coverage for both EXTENSION_SETTINGS and APP_SETTINGS
274 // sync by roughly alternative which one to test.
276 TEST_F(ExtensionSettingsSyncTest
, NoDataDoesNotInvokeSync
) {
277 syncer::ModelType model_type
= syncer::EXTENSION_SETTINGS
;
278 Manifest::Type type
= Manifest::TYPE_EXTENSION
;
280 EXPECT_EQ(0u, GetAllSyncData(model_type
).size());
282 // Have one extension created before sync is set up, the other created after.
283 AddExtensionAndGetStorage("s1", type
);
284 EXPECT_EQ(0u, GetAllSyncData(model_type
).size());
286 GetSyncableService(model_type
)
287 ->MergeDataAndStartSyncing(
289 syncer::SyncDataList(),
290 sync_processor_wrapper_
.Pass(),
291 make_scoped_ptr(new syncer::SyncErrorFactoryMock()));
293 AddExtensionAndGetStorage("s2", type
);
294 EXPECT_EQ(0u, GetAllSyncData(model_type
).size());
296 GetSyncableService(model_type
)->StopSyncing(model_type
);
298 EXPECT_EQ(0u, sync_processor_
->changes().size());
299 EXPECT_EQ(0u, GetAllSyncData(model_type
).size());
302 TEST_F(ExtensionSettingsSyncTest
, InSyncDataDoesNotInvokeSync
) {
303 syncer::ModelType model_type
= syncer::APP_SETTINGS
;
304 Manifest::Type type
= Manifest::TYPE_LEGACY_PACKAGED_APP
;
306 base::StringValue
value1("fooValue");
307 base::ListValue value2
;
308 value2
.Append(new base::StringValue("barValue"));
310 ValueStore
* storage1
= AddExtensionAndGetStorage("s1", type
);
311 ValueStore
* storage2
= AddExtensionAndGetStorage("s2", type
);
313 storage1
->Set(DEFAULTS
, "foo", value1
);
314 storage2
->Set(DEFAULTS
, "bar", value2
);
316 std::map
<std::string
, SettingSyncDataList
> all_sync_data
=
317 GetAllSyncData(model_type
);
318 EXPECT_EQ(2u, all_sync_data
.size());
319 EXPECT_EQ(1u, all_sync_data
["s1"].size());
320 EXPECT_PRED_FORMAT2(ValuesEq
, &value1
, &all_sync_data
["s1"][0].value());
321 EXPECT_EQ(1u, all_sync_data
["s2"].size());
322 EXPECT_PRED_FORMAT2(ValuesEq
, &value2
, &all_sync_data
["s2"][0].value());
324 syncer::SyncDataList sync_data
;
325 sync_data
.push_back(settings_sync_util::CreateData(
326 "s1", "foo", value1
, model_type
));
327 sync_data
.push_back(settings_sync_util::CreateData(
328 "s2", "bar", value2
, model_type
));
330 GetSyncableService(model_type
)
331 ->MergeDataAndStartSyncing(
334 sync_processor_wrapper_
.Pass(),
335 make_scoped_ptr(new syncer::SyncErrorFactoryMock()));
337 // Already in sync, so no changes.
338 EXPECT_EQ(0u, sync_processor_
->changes().size());
340 // Regression test: not-changing the synced value shouldn't result in a sync
341 // change, and changing the synced value should result in an update.
342 storage1
->Set(DEFAULTS
, "foo", value1
);
343 EXPECT_EQ(0u, sync_processor_
->changes().size());
345 storage1
->Set(DEFAULTS
, "foo", value2
);
346 EXPECT_EQ(1u, sync_processor_
->changes().size());
347 SettingSyncData change
= sync_processor_
->GetOnlyChange("s1", "foo");
348 EXPECT_EQ(syncer::SyncChange::ACTION_UPDATE
, change
.change_type());
349 EXPECT_TRUE(value2
.Equals(&change
.value()));
351 GetSyncableService(model_type
)->StopSyncing(model_type
);
354 TEST_F(ExtensionSettingsSyncTest
, LocalDataWithNoSyncDataIsPushedToSync
) {
355 syncer::ModelType model_type
= syncer::EXTENSION_SETTINGS
;
356 Manifest::Type type
= Manifest::TYPE_EXTENSION
;
358 base::StringValue
value1("fooValue");
359 base::ListValue value2
;
360 value2
.Append(new base::StringValue("barValue"));
362 ValueStore
* storage1
= AddExtensionAndGetStorage("s1", type
);
363 ValueStore
* storage2
= AddExtensionAndGetStorage("s2", type
);
365 storage1
->Set(DEFAULTS
, "foo", value1
);
366 storage2
->Set(DEFAULTS
, "bar", value2
);
368 GetSyncableService(model_type
)
369 ->MergeDataAndStartSyncing(
371 syncer::SyncDataList(),
372 sync_processor_wrapper_
.Pass(),
373 make_scoped_ptr(new syncer::SyncErrorFactoryMock()));
375 // All settings should have been pushed to sync.
376 EXPECT_EQ(2u, sync_processor_
->changes().size());
377 SettingSyncData change
= sync_processor_
->GetOnlyChange("s1", "foo");
378 EXPECT_EQ(syncer::SyncChange::ACTION_ADD
, change
.change_type());
379 EXPECT_TRUE(value1
.Equals(&change
.value()));
380 change
= sync_processor_
->GetOnlyChange("s2", "bar");
381 EXPECT_EQ(syncer::SyncChange::ACTION_ADD
, change
.change_type());
382 EXPECT_TRUE(value2
.Equals(&change
.value()));
384 GetSyncableService(model_type
)->StopSyncing(model_type
);
387 TEST_F(ExtensionSettingsSyncTest
, AnySyncDataOverwritesLocalData
) {
388 syncer::ModelType model_type
= syncer::APP_SETTINGS
;
389 Manifest::Type type
= Manifest::TYPE_LEGACY_PACKAGED_APP
;
391 base::StringValue
value1("fooValue");
392 base::ListValue value2
;
393 value2
.Append(new base::StringValue("barValue"));
395 // Maintain dictionaries mirrored to the expected values of the settings in
396 // each storage area.
397 base::DictionaryValue expected1
, expected2
;
399 // Pre-populate one of the storage areas.
400 ValueStore
* storage1
= AddExtensionAndGetStorage("s1", type
);
401 storage1
->Set(DEFAULTS
, "overwriteMe", value1
);
403 syncer::SyncDataList sync_data
;
404 sync_data
.push_back(settings_sync_util::CreateData(
405 "s1", "foo", value1
, model_type
));
406 sync_data
.push_back(settings_sync_util::CreateData(
407 "s2", "bar", value2
, model_type
));
408 GetSyncableService(model_type
)
409 ->MergeDataAndStartSyncing(
412 sync_processor_wrapper_
.Pass(),
413 make_scoped_ptr(new syncer::SyncErrorFactoryMock()));
414 expected1
.Set("foo", value1
.DeepCopy());
415 expected2
.Set("bar", value2
.DeepCopy());
417 ValueStore
* storage2
= AddExtensionAndGetStorage("s2", type
);
419 // All changes should be local, so no sync changes.
420 EXPECT_EQ(0u, sync_processor_
->changes().size());
422 // Sync settings should have been pushed to local settings.
423 EXPECT_PRED_FORMAT2(SettingsEq
, expected1
, storage1
->Get());
424 EXPECT_PRED_FORMAT2(SettingsEq
, expected2
, storage2
->Get());
426 GetSyncableService(model_type
)->StopSyncing(model_type
);
429 TEST_F(ExtensionSettingsSyncTest
, ProcessSyncChanges
) {
430 syncer::ModelType model_type
= syncer::EXTENSION_SETTINGS
;
431 Manifest::Type type
= Manifest::TYPE_EXTENSION
;
433 base::StringValue
value1("fooValue");
434 base::ListValue value2
;
435 value2
.Append(new base::StringValue("barValue"));
437 // Maintain dictionaries mirrored to the expected values of the settings in
438 // each storage area.
439 base::DictionaryValue expected1
, expected2
;
441 // Make storage1 initialised from local data, storage2 initialised from sync.
442 ValueStore
* storage1
= AddExtensionAndGetStorage("s1", type
);
443 ValueStore
* storage2
= AddExtensionAndGetStorage("s2", type
);
445 storage1
->Set(DEFAULTS
, "foo", value1
);
446 expected1
.Set("foo", value1
.DeepCopy());
448 syncer::SyncDataList sync_data
;
449 sync_data
.push_back(settings_sync_util::CreateData(
450 "s2", "bar", value2
, model_type
));
452 GetSyncableService(model_type
)
453 ->MergeDataAndStartSyncing(
456 sync_processor_wrapper_
.Pass(),
457 make_scoped_ptr(new syncer::SyncErrorFactoryMock()));
458 expected2
.Set("bar", value2
.DeepCopy());
460 // Make sync add some settings.
461 syncer::SyncChangeList change_list
;
462 change_list
.push_back(settings_sync_util::CreateAdd(
463 "s1", "bar", value2
, model_type
));
464 change_list
.push_back(settings_sync_util::CreateAdd(
465 "s2", "foo", value1
, model_type
));
466 GetSyncableService(model_type
)->ProcessSyncChanges(FROM_HERE
, change_list
);
467 expected1
.Set("bar", value2
.DeepCopy());
468 expected2
.Set("foo", value1
.DeepCopy());
470 EXPECT_PRED_FORMAT2(SettingsEq
, expected1
, storage1
->Get());
471 EXPECT_PRED_FORMAT2(SettingsEq
, expected2
, storage2
->Get());
473 // Make sync update some settings, storage1 the new setting, storage2 the
476 change_list
.push_back(settings_sync_util::CreateUpdate(
477 "s1", "bar", value2
, model_type
));
478 change_list
.push_back(settings_sync_util::CreateUpdate(
479 "s2", "bar", value1
, model_type
));
480 GetSyncableService(model_type
)->ProcessSyncChanges(FROM_HERE
, change_list
);
481 expected1
.Set("bar", value2
.DeepCopy());
482 expected2
.Set("bar", value1
.DeepCopy());
484 EXPECT_PRED_FORMAT2(SettingsEq
, expected1
, storage1
->Get());
485 EXPECT_PRED_FORMAT2(SettingsEq
, expected2
, storage2
->Get());
487 // Make sync remove some settings, storage1 the initial setting, storage2 the
490 change_list
.push_back(settings_sync_util::CreateDelete(
491 "s1", "foo", model_type
));
492 change_list
.push_back(settings_sync_util::CreateDelete(
493 "s2", "foo", model_type
));
494 GetSyncableService(model_type
)->ProcessSyncChanges(FROM_HERE
, change_list
);
495 expected1
.Remove("foo", NULL
);
496 expected2
.Remove("foo", NULL
);
498 EXPECT_PRED_FORMAT2(SettingsEq
, expected1
, storage1
->Get());
499 EXPECT_PRED_FORMAT2(SettingsEq
, expected2
, storage2
->Get());
501 GetSyncableService(model_type
)->StopSyncing(model_type
);
504 TEST_F(ExtensionSettingsSyncTest
, PushToSync
) {
505 syncer::ModelType model_type
= syncer::APP_SETTINGS
;
506 Manifest::Type type
= Manifest::TYPE_LEGACY_PACKAGED_APP
;
508 base::StringValue
value1("fooValue");
509 base::ListValue value2
;
510 value2
.Append(new base::StringValue("barValue"));
512 // Make storage1/2 initialised from local data, storage3/4 initialised from
514 ValueStore
* storage1
= AddExtensionAndGetStorage("s1", type
);
515 ValueStore
* storage2
= AddExtensionAndGetStorage("s2", type
);
516 ValueStore
* storage3
= AddExtensionAndGetStorage("s3", type
);
517 ValueStore
* storage4
= AddExtensionAndGetStorage("s4", type
);
519 storage1
->Set(DEFAULTS
, "foo", value1
);
520 storage2
->Set(DEFAULTS
, "foo", value1
);
522 syncer::SyncDataList sync_data
;
523 sync_data
.push_back(settings_sync_util::CreateData(
524 "s3", "bar", value2
, model_type
));
525 sync_data
.push_back(settings_sync_util::CreateData(
526 "s4", "bar", value2
, model_type
));
528 GetSyncableService(model_type
)
529 ->MergeDataAndStartSyncing(
532 sync_processor_wrapper_
.Pass(),
533 make_scoped_ptr(new syncer::SyncErrorFactoryMock()));
535 // Add something locally.
536 storage1
->Set(DEFAULTS
, "bar", value2
);
537 storage2
->Set(DEFAULTS
, "bar", value2
);
538 storage3
->Set(DEFAULTS
, "foo", value1
);
539 storage4
->Set(DEFAULTS
, "foo", value1
);
541 SettingSyncData change
= sync_processor_
->GetOnlyChange("s1", "bar");
542 EXPECT_EQ(syncer::SyncChange::ACTION_ADD
, change
.change_type());
543 EXPECT_TRUE(value2
.Equals(&change
.value()));
544 sync_processor_
->GetOnlyChange("s2", "bar");
545 EXPECT_EQ(syncer::SyncChange::ACTION_ADD
, change
.change_type());
546 EXPECT_TRUE(value2
.Equals(&change
.value()));
547 change
= sync_processor_
->GetOnlyChange("s3", "foo");
548 EXPECT_EQ(syncer::SyncChange::ACTION_ADD
, change
.change_type());
549 EXPECT_TRUE(value1
.Equals(&change
.value()));
550 change
= sync_processor_
->GetOnlyChange("s4", "foo");
551 EXPECT_EQ(syncer::SyncChange::ACTION_ADD
, change
.change_type());
552 EXPECT_TRUE(value1
.Equals(&change
.value()));
554 // Change something locally, storage1/3 the new setting and storage2/4 the
555 // initial setting, for all combinations of local vs sync intialisation and
557 sync_processor_
->ClearChanges();
558 storage1
->Set(DEFAULTS
, "bar", value1
);
559 storage2
->Set(DEFAULTS
, "foo", value2
);
560 storage3
->Set(DEFAULTS
, "bar", value1
);
561 storage4
->Set(DEFAULTS
, "foo", value2
);
563 change
= sync_processor_
->GetOnlyChange("s1", "bar");
564 EXPECT_EQ(syncer::SyncChange::ACTION_UPDATE
, change
.change_type());
565 EXPECT_TRUE(value1
.Equals(&change
.value()));
566 change
= sync_processor_
->GetOnlyChange("s2", "foo");
567 EXPECT_EQ(syncer::SyncChange::ACTION_UPDATE
, change
.change_type());
568 EXPECT_TRUE(value2
.Equals(&change
.value()));
569 change
= sync_processor_
->GetOnlyChange("s3", "bar");
570 EXPECT_EQ(syncer::SyncChange::ACTION_UPDATE
, change
.change_type());
571 EXPECT_TRUE(value1
.Equals(&change
.value()));
572 change
= sync_processor_
->GetOnlyChange("s4", "foo");
573 EXPECT_EQ(syncer::SyncChange::ACTION_UPDATE
, change
.change_type());
574 EXPECT_TRUE(value2
.Equals(&change
.value()));
576 // Remove something locally, storage1/3 the new setting and storage2/4 the
577 // initial setting, for all combinations of local vs sync intialisation and
579 sync_processor_
->ClearChanges();
580 storage1
->Remove("foo");
581 storage2
->Remove("bar");
582 storage3
->Remove("foo");
583 storage4
->Remove("bar");
586 syncer::SyncChange::ACTION_DELETE
,
587 sync_processor_
->GetOnlyChange("s1", "foo").change_type());
589 syncer::SyncChange::ACTION_DELETE
,
590 sync_processor_
->GetOnlyChange("s2", "bar").change_type());
592 syncer::SyncChange::ACTION_DELETE
,
593 sync_processor_
->GetOnlyChange("s3", "foo").change_type());
595 syncer::SyncChange::ACTION_DELETE
,
596 sync_processor_
->GetOnlyChange("s4", "bar").change_type());
598 // Remove some nonexistent settings.
599 sync_processor_
->ClearChanges();
600 storage1
->Remove("foo");
601 storage2
->Remove("bar");
602 storage3
->Remove("foo");
603 storage4
->Remove("bar");
605 EXPECT_EQ(0u, sync_processor_
->changes().size());
607 // Clear the rest of the settings. Add the removed ones back first so that
608 // more than one setting is cleared.
609 storage1
->Set(DEFAULTS
, "foo", value1
);
610 storage2
->Set(DEFAULTS
, "bar", value2
);
611 storage3
->Set(DEFAULTS
, "foo", value1
);
612 storage4
->Set(DEFAULTS
, "bar", value2
);
614 sync_processor_
->ClearChanges();
621 syncer::SyncChange::ACTION_DELETE
,
622 sync_processor_
->GetOnlyChange("s1", "foo").change_type());
624 syncer::SyncChange::ACTION_DELETE
,
625 sync_processor_
->GetOnlyChange("s1", "bar").change_type());
627 syncer::SyncChange::ACTION_DELETE
,
628 sync_processor_
->GetOnlyChange("s2", "foo").change_type());
630 syncer::SyncChange::ACTION_DELETE
,
631 sync_processor_
->GetOnlyChange("s2", "bar").change_type());
633 syncer::SyncChange::ACTION_DELETE
,
634 sync_processor_
->GetOnlyChange("s3", "foo").change_type());
636 syncer::SyncChange::ACTION_DELETE
,
637 sync_processor_
->GetOnlyChange("s3", "bar").change_type());
639 syncer::SyncChange::ACTION_DELETE
,
640 sync_processor_
->GetOnlyChange("s4", "foo").change_type());
642 syncer::SyncChange::ACTION_DELETE
,
643 sync_processor_
->GetOnlyChange("s4", "bar").change_type());
645 GetSyncableService(model_type
)->StopSyncing(model_type
);
648 TEST_F(ExtensionSettingsSyncTest
, ExtensionAndAppSettingsSyncSeparately
) {
649 base::StringValue
value1("fooValue");
650 base::ListValue value2
;
651 value2
.Append(new base::StringValue("barValue"));
653 // storage1 is an extension, storage2 is an app.
654 ValueStore
* storage1
= AddExtensionAndGetStorage(
655 "s1", Manifest::TYPE_EXTENSION
);
656 ValueStore
* storage2
= AddExtensionAndGetStorage(
657 "s2", Manifest::TYPE_LEGACY_PACKAGED_APP
);
659 storage1
->Set(DEFAULTS
, "foo", value1
);
660 storage2
->Set(DEFAULTS
, "bar", value2
);
662 std::map
<std::string
, SettingSyncDataList
> extension_sync_data
=
663 GetAllSyncData(syncer::EXTENSION_SETTINGS
);
664 EXPECT_EQ(1u, extension_sync_data
.size());
665 EXPECT_EQ(1u, extension_sync_data
["s1"].size());
666 EXPECT_PRED_FORMAT2(ValuesEq
, &value1
, &extension_sync_data
["s1"][0].value());
668 std::map
<std::string
, SettingSyncDataList
> app_sync_data
=
669 GetAllSyncData(syncer::APP_SETTINGS
);
670 EXPECT_EQ(1u, app_sync_data
.size());
671 EXPECT_EQ(1u, app_sync_data
["s2"].size());
672 EXPECT_PRED_FORMAT2(ValuesEq
, &value2
, &app_sync_data
["s2"][0].value());
674 // Stop each separately, there should be no changes either time.
675 syncer::SyncDataList sync_data
;
676 sync_data
.push_back(settings_sync_util::CreateData(
677 "s1", "foo", value1
, syncer::EXTENSION_SETTINGS
));
679 GetSyncableService(syncer::EXTENSION_SETTINGS
)
680 ->MergeDataAndStartSyncing(
681 syncer::EXTENSION_SETTINGS
,
683 sync_processor_wrapper_
.Pass(),
684 make_scoped_ptr(new syncer::SyncErrorFactoryMock()));
685 GetSyncableService(syncer::EXTENSION_SETTINGS
)->
686 StopSyncing(syncer::EXTENSION_SETTINGS
);
687 EXPECT_EQ(0u, sync_processor_
->changes().size());
690 sync_data
.push_back(settings_sync_util::CreateData(
691 "s2", "bar", value2
, syncer::APP_SETTINGS
));
693 scoped_ptr
<syncer::SyncChangeProcessorWrapperForTest
> app_settings_delegate_(
694 new syncer::SyncChangeProcessorWrapperForTest(sync_processor_
.get()));
695 GetSyncableService(syncer::APP_SETTINGS
)
696 ->MergeDataAndStartSyncing(
697 syncer::APP_SETTINGS
,
699 app_settings_delegate_
.Pass(),
700 make_scoped_ptr(new syncer::SyncErrorFactoryMock()));
701 GetSyncableService(syncer::APP_SETTINGS
)->
702 StopSyncing(syncer::APP_SETTINGS
);
703 EXPECT_EQ(0u, sync_processor_
->changes().size());
706 TEST_F(ExtensionSettingsSyncTest
, FailingStartSyncingDisablesSync
) {
707 syncer::ModelType model_type
= syncer::EXTENSION_SETTINGS
;
708 Manifest::Type type
= Manifest::TYPE_EXTENSION
;
710 base::StringValue
fooValue("fooValue");
711 base::StringValue
barValue("barValue");
713 // There is a bit of a convoluted method to get storage areas that can fail;
714 // hand out TestingValueStore object then toggle them failing/succeeding
716 TestingValueStoreFactory
* testing_factory
= new TestingValueStoreFactory();
717 storage_factory_
->Reset(testing_factory
);
719 ValueStore
* good
= AddExtensionAndGetStorage("good", type
);
720 ValueStore
* bad
= AddExtensionAndGetStorage("bad", type
);
722 // Make bad fail for incoming sync changes.
723 testing_factory
->GetExisting("bad")->set_error_code(ValueStore::CORRUPTION
);
725 syncer::SyncDataList sync_data
;
726 sync_data
.push_back(settings_sync_util::CreateData(
727 "good", "foo", fooValue
, model_type
));
728 sync_data
.push_back(settings_sync_util::CreateData(
729 "bad", "foo", fooValue
, model_type
));
730 GetSyncableService(model_type
)
731 ->MergeDataAndStartSyncing(
734 sync_processor_wrapper_
.Pass(),
735 make_scoped_ptr(new syncer::SyncErrorFactoryMock()));
737 testing_factory
->GetExisting("bad")->set_error_code(ValueStore::OK
);
740 base::DictionaryValue dict
;
741 dict
.Set("foo", fooValue
.DeepCopy());
742 EXPECT_PRED_FORMAT2(SettingsEq
, dict
, good
->Get());
745 base::DictionaryValue dict
;
746 EXPECT_PRED_FORMAT2(SettingsEq
, dict
, bad
->Get());
749 // Changes made to good should be sent to sync, changes from bad shouldn't.
750 sync_processor_
->ClearChanges();
751 good
->Set(DEFAULTS
, "bar", barValue
);
752 bad
->Set(DEFAULTS
, "bar", barValue
);
755 syncer::SyncChange::ACTION_ADD
,
756 sync_processor_
->GetOnlyChange("good", "bar").change_type());
757 EXPECT_EQ(1u, sync_processor_
->changes().size());
760 base::DictionaryValue dict
;
761 dict
.Set("foo", fooValue
.DeepCopy());
762 dict
.Set("bar", barValue
.DeepCopy());
763 EXPECT_PRED_FORMAT2(SettingsEq
, dict
, good
->Get());
766 base::DictionaryValue dict
;
767 dict
.Set("bar", barValue
.DeepCopy());
768 EXPECT_PRED_FORMAT2(SettingsEq
, dict
, bad
->Get());
771 // Changes received from sync should go to good but not bad (even when it's
774 syncer::SyncChangeList change_list
;
775 change_list
.push_back(settings_sync_util::CreateUpdate(
776 "good", "foo", barValue
, model_type
));
777 // (Sending UPDATE here even though it's adding, since that's what the state
778 // of sync is. In any case, it won't work.)
779 change_list
.push_back(settings_sync_util::CreateUpdate(
780 "bad", "foo", barValue
, model_type
));
781 GetSyncableService(model_type
)->ProcessSyncChanges(FROM_HERE
, change_list
);
785 base::DictionaryValue dict
;
786 dict
.Set("foo", barValue
.DeepCopy());
787 dict
.Set("bar", barValue
.DeepCopy());
788 EXPECT_PRED_FORMAT2(SettingsEq
, dict
, good
->Get());
791 base::DictionaryValue dict
;
792 dict
.Set("bar", barValue
.DeepCopy());
793 EXPECT_PRED_FORMAT2(SettingsEq
, dict
, bad
->Get());
796 // Changes made to bad still shouldn't go to sync, even though it didn't fail
798 sync_processor_
->ClearChanges();
799 good
->Set(DEFAULTS
, "bar", fooValue
);
800 bad
->Set(DEFAULTS
, "bar", fooValue
);
803 syncer::SyncChange::ACTION_UPDATE
,
804 sync_processor_
->GetOnlyChange("good", "bar").change_type());
805 EXPECT_EQ(1u, sync_processor_
->changes().size());
808 base::DictionaryValue dict
;
809 dict
.Set("foo", barValue
.DeepCopy());
810 dict
.Set("bar", fooValue
.DeepCopy());
811 EXPECT_PRED_FORMAT2(SettingsEq
, dict
, good
->Get());
814 base::DictionaryValue dict
;
815 dict
.Set("bar", fooValue
.DeepCopy());
816 EXPECT_PRED_FORMAT2(SettingsEq
, dict
, bad
->Get());
819 // Failing ProcessSyncChanges shouldn't go to the storage.
820 testing_factory
->GetExisting("bad")->set_error_code(ValueStore::CORRUPTION
);
822 syncer::SyncChangeList change_list
;
823 change_list
.push_back(settings_sync_util::CreateUpdate(
824 "good", "foo", fooValue
, model_type
));
826 change_list
.push_back(settings_sync_util::CreateUpdate(
827 "bad", "foo", fooValue
, model_type
));
828 GetSyncableService(model_type
)->ProcessSyncChanges(FROM_HERE
, change_list
);
830 testing_factory
->GetExisting("bad")->set_error_code(ValueStore::OK
);
833 base::DictionaryValue dict
;
834 dict
.Set("foo", fooValue
.DeepCopy());
835 dict
.Set("bar", fooValue
.DeepCopy());
836 EXPECT_PRED_FORMAT2(SettingsEq
, dict
, good
->Get());
839 base::DictionaryValue dict
;
840 dict
.Set("bar", fooValue
.DeepCopy());
841 EXPECT_PRED_FORMAT2(SettingsEq
, dict
, bad
->Get());
844 // Restarting sync should make bad start syncing again.
845 sync_processor_
->ClearChanges();
846 GetSyncableService(model_type
)->StopSyncing(model_type
);
847 sync_processor_wrapper_
.reset(
848 new syncer::SyncChangeProcessorWrapperForTest(sync_processor_
.get()));
849 GetSyncableService(model_type
)
850 ->MergeDataAndStartSyncing(
852 syncer::SyncDataList(),
853 sync_processor_wrapper_
.Pass(),
854 make_scoped_ptr(new syncer::SyncErrorFactoryMock()));
856 // Local settings will have been pushed to sync, since it's empty (in this
857 // test; presumably it wouldn't be live, since we've been getting changes).
859 syncer::SyncChange::ACTION_ADD
,
860 sync_processor_
->GetOnlyChange("good", "foo").change_type());
862 syncer::SyncChange::ACTION_ADD
,
863 sync_processor_
->GetOnlyChange("good", "bar").change_type());
865 syncer::SyncChange::ACTION_ADD
,
866 sync_processor_
->GetOnlyChange("bad", "bar").change_type());
867 EXPECT_EQ(3u, sync_processor_
->changes().size());
869 // Live local changes now get pushed, too.
870 sync_processor_
->ClearChanges();
871 good
->Set(DEFAULTS
, "bar", barValue
);
872 bad
->Set(DEFAULTS
, "bar", barValue
);
875 syncer::SyncChange::ACTION_UPDATE
,
876 sync_processor_
->GetOnlyChange("good", "bar").change_type());
878 syncer::SyncChange::ACTION_UPDATE
,
879 sync_processor_
->GetOnlyChange("bad", "bar").change_type());
880 EXPECT_EQ(2u, sync_processor_
->changes().size());
882 // And ProcessSyncChanges work, too.
884 syncer::SyncChangeList change_list
;
885 change_list
.push_back(settings_sync_util::CreateUpdate(
886 "good", "bar", fooValue
, model_type
));
887 change_list
.push_back(settings_sync_util::CreateUpdate(
888 "bad", "bar", fooValue
, model_type
));
889 GetSyncableService(model_type
)->ProcessSyncChanges(FROM_HERE
, change_list
);
893 base::DictionaryValue dict
;
894 dict
.Set("foo", fooValue
.DeepCopy());
895 dict
.Set("bar", fooValue
.DeepCopy());
896 EXPECT_PRED_FORMAT2(SettingsEq
, dict
, good
->Get());
899 base::DictionaryValue dict
;
900 dict
.Set("bar", fooValue
.DeepCopy());
901 EXPECT_PRED_FORMAT2(SettingsEq
, dict
, bad
->Get());
905 TEST_F(ExtensionSettingsSyncTest
, FailingProcessChangesDisablesSync
) {
906 // The test above tests a failing ProcessSyncChanges too, but here test with
907 // an initially passing MergeDataAndStartSyncing.
908 syncer::ModelType model_type
= syncer::APP_SETTINGS
;
909 Manifest::Type type
= Manifest::TYPE_LEGACY_PACKAGED_APP
;
911 base::StringValue
fooValue("fooValue");
912 base::StringValue
barValue("barValue");
914 TestingValueStoreFactory
* testing_factory
= new TestingValueStoreFactory();
915 storage_factory_
->Reset(testing_factory
);
917 ValueStore
* good
= AddExtensionAndGetStorage("good", type
);
918 ValueStore
* bad
= AddExtensionAndGetStorage("bad", type
);
920 // Unlike before, initially succeeding MergeDataAndStartSyncing.
922 syncer::SyncDataList sync_data
;
923 sync_data
.push_back(settings_sync_util::CreateData(
924 "good", "foo", fooValue
, model_type
));
925 sync_data
.push_back(settings_sync_util::CreateData(
926 "bad", "foo", fooValue
, model_type
));
927 GetSyncableService(model_type
)
928 ->MergeDataAndStartSyncing(
931 sync_processor_wrapper_
.Pass(),
932 make_scoped_ptr(new syncer::SyncErrorFactoryMock()));
935 EXPECT_EQ(0u, sync_processor_
->changes().size());
938 base::DictionaryValue dict
;
939 dict
.Set("foo", fooValue
.DeepCopy());
940 EXPECT_PRED_FORMAT2(SettingsEq
, dict
, good
->Get());
943 base::DictionaryValue dict
;
944 dict
.Set("foo", fooValue
.DeepCopy());
945 EXPECT_PRED_FORMAT2(SettingsEq
, dict
, bad
->Get());
948 // Now fail ProcessSyncChanges for bad.
949 testing_factory
->GetExisting("bad")->set_error_code(ValueStore::CORRUPTION
);
951 syncer::SyncChangeList change_list
;
952 change_list
.push_back(settings_sync_util::CreateAdd(
953 "good", "bar", barValue
, model_type
));
954 change_list
.push_back(settings_sync_util::CreateAdd(
955 "bad", "bar", barValue
, model_type
));
956 GetSyncableService(model_type
)->ProcessSyncChanges(FROM_HERE
, change_list
);
958 testing_factory
->GetExisting("bad")->set_error_code(ValueStore::OK
);
961 base::DictionaryValue dict
;
962 dict
.Set("foo", fooValue
.DeepCopy());
963 dict
.Set("bar", barValue
.DeepCopy());
964 EXPECT_PRED_FORMAT2(SettingsEq
, dict
, good
->Get());
967 base::DictionaryValue dict
;
968 dict
.Set("foo", fooValue
.DeepCopy());
969 EXPECT_PRED_FORMAT2(SettingsEq
, dict
, bad
->Get());
972 // No more changes sent to sync for bad.
973 sync_processor_
->ClearChanges();
974 good
->Set(DEFAULTS
, "foo", barValue
);
975 bad
->Set(DEFAULTS
, "foo", barValue
);
978 syncer::SyncChange::ACTION_UPDATE
,
979 sync_processor_
->GetOnlyChange("good", "foo").change_type());
980 EXPECT_EQ(1u, sync_processor_
->changes().size());
982 // No more changes received from sync should go to bad.
984 syncer::SyncChangeList change_list
;
985 change_list
.push_back(settings_sync_util::CreateAdd(
986 "good", "foo", fooValue
, model_type
));
987 change_list
.push_back(settings_sync_util::CreateAdd(
988 "bad", "foo", fooValue
, model_type
));
989 GetSyncableService(model_type
)->ProcessSyncChanges(FROM_HERE
, change_list
);
993 base::DictionaryValue dict
;
994 dict
.Set("foo", fooValue
.DeepCopy());
995 dict
.Set("bar", barValue
.DeepCopy());
996 EXPECT_PRED_FORMAT2(SettingsEq
, dict
, good
->Get());
999 base::DictionaryValue dict
;
1000 dict
.Set("foo", barValue
.DeepCopy());
1001 EXPECT_PRED_FORMAT2(SettingsEq
, dict
, bad
->Get());
1005 TEST_F(ExtensionSettingsSyncTest
, FailingGetAllSyncDataDoesntStopSync
) {
1006 syncer::ModelType model_type
= syncer::EXTENSION_SETTINGS
;
1007 Manifest::Type type
= Manifest::TYPE_EXTENSION
;
1009 base::StringValue
fooValue("fooValue");
1010 base::StringValue
barValue("barValue");
1012 TestingValueStoreFactory
* testing_factory
= new TestingValueStoreFactory();
1013 storage_factory_
->Reset(testing_factory
);
1015 ValueStore
* good
= AddExtensionAndGetStorage("good", type
);
1016 ValueStore
* bad
= AddExtensionAndGetStorage("bad", type
);
1018 good
->Set(DEFAULTS
, "foo", fooValue
);
1019 bad
->Set(DEFAULTS
, "foo", fooValue
);
1021 // Even though bad will fail to get all sync data, sync data should still
1022 // include that from good.
1023 testing_factory
->GetExisting("bad")->set_error_code(ValueStore::CORRUPTION
);
1025 syncer::SyncDataList all_sync_data
=
1026 GetSyncableService(model_type
)->GetAllSyncData(model_type
);
1027 EXPECT_EQ(1u, all_sync_data
.size());
1028 EXPECT_EQ("good/foo", syncer::SyncDataLocal(all_sync_data
[0]).GetTag());
1030 testing_factory
->GetExisting("bad")->set_error_code(ValueStore::OK
);
1032 // Sync shouldn't be disabled for good (nor bad -- but this is unimportant).
1033 GetSyncableService(model_type
)
1034 ->MergeDataAndStartSyncing(
1036 syncer::SyncDataList(),
1037 sync_processor_wrapper_
.Pass(),
1038 make_scoped_ptr(new syncer::SyncErrorFactoryMock()));
1041 syncer::SyncChange::ACTION_ADD
,
1042 sync_processor_
->GetOnlyChange("good", "foo").change_type());
1044 syncer::SyncChange::ACTION_ADD
,
1045 sync_processor_
->GetOnlyChange("bad", "foo").change_type());
1046 EXPECT_EQ(2u, sync_processor_
->changes().size());
1048 sync_processor_
->ClearChanges();
1049 good
->Set(DEFAULTS
, "bar", barValue
);
1050 bad
->Set(DEFAULTS
, "bar", barValue
);
1053 syncer::SyncChange::ACTION_ADD
,
1054 sync_processor_
->GetOnlyChange("good", "bar").change_type());
1056 syncer::SyncChange::ACTION_ADD
,
1057 sync_processor_
->GetOnlyChange("bad", "bar").change_type());
1058 EXPECT_EQ(2u, sync_processor_
->changes().size());
1061 TEST_F(ExtensionSettingsSyncTest
, FailureToReadChangesToPushDisablesSync
) {
1062 syncer::ModelType model_type
= syncer::APP_SETTINGS
;
1063 Manifest::Type type
= Manifest::TYPE_LEGACY_PACKAGED_APP
;
1065 base::StringValue
fooValue("fooValue");
1066 base::StringValue
barValue("barValue");
1068 TestingValueStoreFactory
* testing_factory
= new TestingValueStoreFactory();
1069 storage_factory_
->Reset(testing_factory
);
1071 ValueStore
* good
= AddExtensionAndGetStorage("good", type
);
1072 ValueStore
* bad
= AddExtensionAndGetStorage("bad", type
);
1074 good
->Set(DEFAULTS
, "foo", fooValue
);
1075 bad
->Set(DEFAULTS
, "foo", fooValue
);
1077 // good will successfully push foo:fooValue to sync, but bad will fail to
1078 // get them so won't.
1079 testing_factory
->GetExisting("bad")->set_error_code(ValueStore::CORRUPTION
);
1080 GetSyncableService(model_type
)
1081 ->MergeDataAndStartSyncing(
1083 syncer::SyncDataList(),
1084 sync_processor_wrapper_
.Pass(),
1085 make_scoped_ptr(new syncer::SyncErrorFactoryMock()));
1086 testing_factory
->GetExisting("bad")->set_error_code(ValueStore::OK
);
1089 syncer::SyncChange::ACTION_ADD
,
1090 sync_processor_
->GetOnlyChange("good", "foo").change_type());
1091 EXPECT_EQ(1u, sync_processor_
->changes().size());
1093 // bad should now be disabled for sync.
1094 sync_processor_
->ClearChanges();
1095 good
->Set(DEFAULTS
, "bar", barValue
);
1096 bad
->Set(DEFAULTS
, "bar", barValue
);
1099 syncer::SyncChange::ACTION_ADD
,
1100 sync_processor_
->GetOnlyChange("good", "bar").change_type());
1101 EXPECT_EQ(1u, sync_processor_
->changes().size());
1104 syncer::SyncChangeList change_list
;
1105 change_list
.push_back(settings_sync_util::CreateUpdate(
1106 "good", "foo", barValue
, model_type
));
1107 // (Sending ADD here even though it's updating, since that's what the state
1108 // of sync is. In any case, it won't work.)
1109 change_list
.push_back(settings_sync_util::CreateAdd(
1110 "bad", "foo", barValue
, model_type
));
1111 GetSyncableService(model_type
)->ProcessSyncChanges(FROM_HERE
, change_list
);
1115 base::DictionaryValue dict
;
1116 dict
.Set("foo", barValue
.DeepCopy());
1117 dict
.Set("bar", barValue
.DeepCopy());
1118 EXPECT_PRED_FORMAT2(SettingsEq
, dict
, good
->Get());
1121 base::DictionaryValue dict
;
1122 dict
.Set("foo", fooValue
.DeepCopy());
1123 dict
.Set("bar", barValue
.DeepCopy());
1124 EXPECT_PRED_FORMAT2(SettingsEq
, dict
, bad
->Get());
1127 // Re-enabling sync without failing should cause the local changes from bad
1128 // to be pushed to sync successfully, as should future changes to bad.
1129 sync_processor_
->ClearChanges();
1130 GetSyncableService(model_type
)->StopSyncing(model_type
);
1131 sync_processor_wrapper_
.reset(
1132 new syncer::SyncChangeProcessorWrapperForTest(sync_processor_
.get()));
1133 GetSyncableService(model_type
)
1134 ->MergeDataAndStartSyncing(
1136 syncer::SyncDataList(),
1137 sync_processor_wrapper_
.Pass(),
1138 make_scoped_ptr(new syncer::SyncErrorFactoryMock()));
1141 syncer::SyncChange::ACTION_ADD
,
1142 sync_processor_
->GetOnlyChange("good", "foo").change_type());
1144 syncer::SyncChange::ACTION_ADD
,
1145 sync_processor_
->GetOnlyChange("good", "bar").change_type());
1147 syncer::SyncChange::ACTION_ADD
,
1148 sync_processor_
->GetOnlyChange("bad", "foo").change_type());
1150 syncer::SyncChange::ACTION_ADD
,
1151 sync_processor_
->GetOnlyChange("bad", "bar").change_type());
1152 EXPECT_EQ(4u, sync_processor_
->changes().size());
1154 sync_processor_
->ClearChanges();
1155 good
->Set(DEFAULTS
, "bar", fooValue
);
1156 bad
->Set(DEFAULTS
, "bar", fooValue
);
1159 syncer::SyncChange::ACTION_UPDATE
,
1160 sync_processor_
->GetOnlyChange("good", "bar").change_type());
1162 syncer::SyncChange::ACTION_UPDATE
,
1163 sync_processor_
->GetOnlyChange("good", "bar").change_type());
1164 EXPECT_EQ(2u, sync_processor_
->changes().size());
1167 TEST_F(ExtensionSettingsSyncTest
, FailureToPushLocalStateDisablesSync
) {
1168 syncer::ModelType model_type
= syncer::EXTENSION_SETTINGS
;
1169 Manifest::Type type
= Manifest::TYPE_EXTENSION
;
1171 base::StringValue
fooValue("fooValue");
1172 base::StringValue
barValue("barValue");
1174 TestingValueStoreFactory
* testing_factory
= new TestingValueStoreFactory();
1175 storage_factory_
->Reset(testing_factory
);
1177 ValueStore
* good
= AddExtensionAndGetStorage("good", type
);
1178 ValueStore
* bad
= AddExtensionAndGetStorage("bad", type
);
1180 // Only set bad; setting good will cause it to fail below.
1181 bad
->Set(DEFAULTS
, "foo", fooValue
);
1183 sync_processor_
->set_fail_all_requests(true);
1184 GetSyncableService(model_type
)
1185 ->MergeDataAndStartSyncing(
1187 syncer::SyncDataList(),
1188 sync_processor_wrapper_
.Pass(),
1189 make_scoped_ptr(new syncer::SyncErrorFactoryMock()));
1190 sync_processor_
->set_fail_all_requests(false);
1192 // Changes from good will be send to sync, changes from bad won't.
1193 sync_processor_
->ClearChanges();
1194 good
->Set(DEFAULTS
, "foo", barValue
);
1195 bad
->Set(DEFAULTS
, "foo", barValue
);
1198 syncer::SyncChange::ACTION_ADD
,
1199 sync_processor_
->GetOnlyChange("good", "foo").change_type());
1200 EXPECT_EQ(1u, sync_processor_
->changes().size());
1202 // Changes from sync will be sent to good, not to bad.
1204 syncer::SyncChangeList change_list
;
1205 change_list
.push_back(settings_sync_util::CreateAdd(
1206 "good", "bar", barValue
, model_type
));
1207 change_list
.push_back(settings_sync_util::CreateAdd(
1208 "bad", "bar", barValue
, model_type
));
1209 GetSyncableService(model_type
)->ProcessSyncChanges(FROM_HERE
, change_list
);
1213 base::DictionaryValue dict
;
1214 dict
.Set("foo", barValue
.DeepCopy());
1215 dict
.Set("bar", barValue
.DeepCopy());
1216 EXPECT_PRED_FORMAT2(SettingsEq
, dict
, good
->Get());
1219 base::DictionaryValue dict
;
1220 dict
.Set("foo", barValue
.DeepCopy());
1221 EXPECT_PRED_FORMAT2(SettingsEq
, dict
, bad
->Get());
1224 // Restarting sync makes everything work again.
1225 sync_processor_
->ClearChanges();
1226 GetSyncableService(model_type
)->StopSyncing(model_type
);
1227 sync_processor_wrapper_
.reset(
1228 new syncer::SyncChangeProcessorWrapperForTest(sync_processor_
.get()));
1229 GetSyncableService(model_type
)
1230 ->MergeDataAndStartSyncing(
1232 syncer::SyncDataList(),
1233 sync_processor_wrapper_
.Pass(),
1234 make_scoped_ptr(new syncer::SyncErrorFactoryMock()));
1237 syncer::SyncChange::ACTION_ADD
,
1238 sync_processor_
->GetOnlyChange("good", "foo").change_type());
1240 syncer::SyncChange::ACTION_ADD
,
1241 sync_processor_
->GetOnlyChange("good", "bar").change_type());
1243 syncer::SyncChange::ACTION_ADD
,
1244 sync_processor_
->GetOnlyChange("bad", "foo").change_type());
1245 EXPECT_EQ(3u, sync_processor_
->changes().size());
1247 sync_processor_
->ClearChanges();
1248 good
->Set(DEFAULTS
, "foo", fooValue
);
1249 bad
->Set(DEFAULTS
, "foo", fooValue
);
1252 syncer::SyncChange::ACTION_UPDATE
,
1253 sync_processor_
->GetOnlyChange("good", "foo").change_type());
1255 syncer::SyncChange::ACTION_UPDATE
,
1256 sync_processor_
->GetOnlyChange("good", "foo").change_type());
1257 EXPECT_EQ(2u, sync_processor_
->changes().size());
1260 TEST_F(ExtensionSettingsSyncTest
, FailureToPushLocalChangeDisablesSync
) {
1261 syncer::ModelType model_type
= syncer::EXTENSION_SETTINGS
;
1262 Manifest::Type type
= Manifest::TYPE_EXTENSION
;
1264 base::StringValue
fooValue("fooValue");
1265 base::StringValue
barValue("barValue");
1267 TestingValueStoreFactory
* testing_factory
= new TestingValueStoreFactory();
1268 storage_factory_
->Reset(testing_factory
);
1270 ValueStore
* good
= AddExtensionAndGetStorage("good", type
);
1271 ValueStore
* bad
= AddExtensionAndGetStorage("bad", type
);
1273 GetSyncableService(model_type
)
1274 ->MergeDataAndStartSyncing(
1276 syncer::SyncDataList(),
1277 sync_processor_wrapper_
.Pass(),
1278 make_scoped_ptr(new syncer::SyncErrorFactoryMock()));
1280 // bad will fail to send changes.
1281 good
->Set(DEFAULTS
, "foo", fooValue
);
1282 sync_processor_
->set_fail_all_requests(true);
1283 bad
->Set(DEFAULTS
, "foo", fooValue
);
1284 sync_processor_
->set_fail_all_requests(false);
1287 syncer::SyncChange::ACTION_ADD
,
1288 sync_processor_
->GetOnlyChange("good", "foo").change_type());
1289 EXPECT_EQ(1u, sync_processor_
->changes().size());
1291 // No further changes should be sent from bad.
1292 sync_processor_
->ClearChanges();
1293 good
->Set(DEFAULTS
, "foo", barValue
);
1294 bad
->Set(DEFAULTS
, "foo", barValue
);
1297 syncer::SyncChange::ACTION_UPDATE
,
1298 sync_processor_
->GetOnlyChange("good", "foo").change_type());
1299 EXPECT_EQ(1u, sync_processor_
->changes().size());
1301 // Changes from sync will be sent to good, not to bad.
1303 syncer::SyncChangeList change_list
;
1304 change_list
.push_back(settings_sync_util::CreateAdd(
1305 "good", "bar", barValue
, model_type
));
1306 change_list
.push_back(settings_sync_util::CreateAdd(
1307 "bad", "bar", barValue
, model_type
));
1308 GetSyncableService(model_type
)->ProcessSyncChanges(FROM_HERE
, change_list
);
1312 base::DictionaryValue dict
;
1313 dict
.Set("foo", barValue
.DeepCopy());
1314 dict
.Set("bar", barValue
.DeepCopy());
1315 EXPECT_PRED_FORMAT2(SettingsEq
, dict
, good
->Get());
1318 base::DictionaryValue dict
;
1319 dict
.Set("foo", barValue
.DeepCopy());
1320 EXPECT_PRED_FORMAT2(SettingsEq
, dict
, bad
->Get());
1323 // Restarting sync makes everything work again.
1324 sync_processor_
->ClearChanges();
1325 GetSyncableService(model_type
)->StopSyncing(model_type
);
1326 sync_processor_wrapper_
.reset(
1327 new syncer::SyncChangeProcessorWrapperForTest(sync_processor_
.get()));
1328 GetSyncableService(model_type
)
1329 ->MergeDataAndStartSyncing(
1331 syncer::SyncDataList(),
1332 sync_processor_wrapper_
.Pass(),
1333 make_scoped_ptr(new syncer::SyncErrorFactoryMock()));
1336 syncer::SyncChange::ACTION_ADD
,
1337 sync_processor_
->GetOnlyChange("good", "foo").change_type());
1339 syncer::SyncChange::ACTION_ADD
,
1340 sync_processor_
->GetOnlyChange("good", "bar").change_type());
1342 syncer::SyncChange::ACTION_ADD
,
1343 sync_processor_
->GetOnlyChange("bad", "foo").change_type());
1344 EXPECT_EQ(3u, sync_processor_
->changes().size());
1346 sync_processor_
->ClearChanges();
1347 good
->Set(DEFAULTS
, "foo", fooValue
);
1348 bad
->Set(DEFAULTS
, "foo", fooValue
);
1351 syncer::SyncChange::ACTION_UPDATE
,
1352 sync_processor_
->GetOnlyChange("good", "foo").change_type());
1354 syncer::SyncChange::ACTION_UPDATE
,
1355 sync_processor_
->GetOnlyChange("good", "foo").change_type());
1356 EXPECT_EQ(2u, sync_processor_
->changes().size());
1359 TEST_F(ExtensionSettingsSyncTest
,
1360 LargeOutgoingChangeRejectedButIncomingAccepted
) {
1361 syncer::ModelType model_type
= syncer::APP_SETTINGS
;
1362 Manifest::Type type
= Manifest::TYPE_LEGACY_PACKAGED_APP
;
1364 // This value should be larger than the limit in sync_storage_backend.cc.
1365 std::string string_10k
;
1366 for (size_t i
= 0; i
< 10000; ++i
) {
1367 string_10k
.append("a");
1369 base::StringValue
large_value(string_10k
);
1371 GetSyncableService(model_type
)
1372 ->MergeDataAndStartSyncing(
1374 syncer::SyncDataList(),
1375 sync_processor_wrapper_
.Pass(),
1376 make_scoped_ptr(new syncer::SyncErrorFactoryMock()));
1378 // Large local change rejected and doesn't get sent out.
1379 ValueStore
* storage1
= AddExtensionAndGetStorage("s1", type
);
1380 EXPECT_TRUE(storage1
->Set(DEFAULTS
, "large_value", large_value
)->HasError());
1381 EXPECT_EQ(0u, sync_processor_
->changes().size());
1383 // Large incoming change should still get accepted.
1384 ValueStore
* storage2
= AddExtensionAndGetStorage("s2", type
);
1386 syncer::SyncChangeList change_list
;
1387 change_list
.push_back(settings_sync_util::CreateAdd(
1388 "s1", "large_value", large_value
, model_type
));
1389 change_list
.push_back(settings_sync_util::CreateAdd(
1390 "s2", "large_value", large_value
, model_type
));
1391 GetSyncableService(model_type
)->ProcessSyncChanges(FROM_HERE
, change_list
);
1394 base::DictionaryValue expected
;
1395 expected
.Set("large_value", large_value
.DeepCopy());
1396 EXPECT_PRED_FORMAT2(SettingsEq
, expected
, storage1
->Get());
1397 EXPECT_PRED_FORMAT2(SettingsEq
, expected
, storage2
->Get());
1400 GetSyncableService(model_type
)->StopSyncing(model_type
);
1403 TEST_F(ExtensionSettingsSyncTest
, Dots
) {
1404 syncer::ModelType model_type
= syncer::EXTENSION_SETTINGS
;
1405 Manifest::Type type
= Manifest::TYPE_EXTENSION
;
1407 ValueStore
* storage
= AddExtensionAndGetStorage("ext", type
);
1410 syncer::SyncDataList sync_data_list
;
1411 scoped_ptr
<base::Value
> string_value(new base::StringValue("value"));
1412 sync_data_list
.push_back(settings_sync_util::CreateData(
1413 "ext", "key.with.dot", *string_value
, model_type
));
1415 GetSyncableService(model_type
)
1416 ->MergeDataAndStartSyncing(
1419 sync_processor_wrapper_
.Pass(),
1420 make_scoped_ptr(new syncer::SyncErrorFactoryMock()));
1423 // Test dots in keys that come from sync.
1425 ValueStore::ReadResult data
= storage
->Get();
1426 ASSERT_FALSE(data
->HasError());
1428 base::DictionaryValue expected_data
;
1429 expected_data
.SetWithoutPathExpansion(
1431 new base::StringValue("value"));
1432 EXPECT_TRUE(base::Value::Equals(&expected_data
, &data
->settings()));
1435 // Test dots in keys going to sync.
1437 scoped_ptr
<base::Value
> string_value(new base::StringValue("spot"));
1438 storage
->Set(DEFAULTS
, "key.with.spot", *string_value
);
1440 ASSERT_EQ(1u, sync_processor_
->changes().size());
1441 SettingSyncData sync_data
= sync_processor_
->changes()[0];
1442 EXPECT_EQ(syncer::SyncChange::ACTION_ADD
, sync_data
.change_type());
1443 EXPECT_EQ("ext", sync_data
.extension_id());
1444 EXPECT_EQ("key.with.spot", sync_data
.key());
1445 EXPECT_TRUE(sync_data
.value().Equals(string_value
.get()));
1449 // In other (frontend) tests, we assume that the result of GetStorage
1450 // is a pointer to the a Storage owned by a Frontend object, but for
1451 // the unlimitedStorage case, this might not be true. So, write the
1452 // tests in a "callback" style. We should really rewrite all tests to
1453 // be asynchronous in this way.
1457 static void UnlimitedSyncStorageTestCallback(ValueStore
* sync_storage
) {
1458 // Sync storage should still run out after ~100K; the unlimitedStorage
1459 // permission can't apply to sync.
1460 scoped_ptr
<base::Value
> kilobyte
= util::CreateKilobyte();
1461 for (int i
= 0; i
< 100; ++i
) {
1463 ValueStore::DEFAULTS
, base::StringPrintf("%d", i
), *kilobyte
);
1466 EXPECT_TRUE(sync_storage
->Set(ValueStore::DEFAULTS
, "WillError", *kilobyte
)
1470 static void UnlimitedLocalStorageTestCallback(ValueStore
* local_storage
) {
1471 // Local storage should never run out.
1472 scoped_ptr
<base::Value
> megabyte
= util::CreateMegabyte();
1473 for (int i
= 0; i
< 7; ++i
) {
1475 ValueStore::DEFAULTS
, base::StringPrintf("%d", i
), *megabyte
);
1478 EXPECT_FALSE(local_storage
->Set(ValueStore::DEFAULTS
, "WontError", *megabyte
)
1485 // See: http://crbug.com/227296
1486 #define MAYBE_UnlimitedStorageForLocalButNotSync \
1487 DISABLED_UnlimitedStorageForLocalButNotSync
1489 #define MAYBE_UnlimitedStorageForLocalButNotSync \
1490 UnlimitedStorageForLocalButNotSync
1492 TEST_F(ExtensionSettingsSyncTest
, MAYBE_UnlimitedStorageForLocalButNotSync
) {
1493 const std::string id
= "ext";
1494 std::set
<std::string
> permissions
;
1495 permissions
.insert("unlimitedStorage");
1496 scoped_refptr
<const Extension
> extension
=
1497 util::AddExtensionWithIdAndPermissions(
1498 profile_
.get(), id
, Manifest::TYPE_EXTENSION
, permissions
);
1500 frontend_
->RunWithStorage(extension
,
1501 settings_namespace::SYNC
,
1502 base::Bind(&UnlimitedSyncStorageTestCallback
));
1503 frontend_
->RunWithStorage(extension
,
1504 settings_namespace::LOCAL
,
1505 base::Bind(&UnlimitedLocalStorageTestCallback
));
1507 base::MessageLoop::current()->RunUntilIdle();
1510 } // namespace extensions