Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1540)

Side by Side Diff: chrome/browser/extensions/settings/settings_sync_unittest.cc

Issue 8539037: Extension Settings API: make it so that when changes received from Sync fail to (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: comments, sync Created 9 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "testing/gtest/include/gtest/gtest.h" 5 #include "testing/gtest/include/gtest/gtest.h"
6 6
7 #include "base/bind.h" 7 #include "base/bind.h"
8 #include "base/json/json_reader.h" 8 #include "base/json/json_reader.h"
9 #include "base/json/json_writer.h" 9 #include "base/json/json_writer.h"
10 #include "base/memory/scoped_ptr.h" 10 #include "base/memory/scoped_ptr.h"
11 #include "base/message_loop.h" 11 #include "base/message_loop.h"
12 #include "base/scoped_temp_dir.h" 12 #include "base/scoped_temp_dir.h"
13 #include "base/task.h" 13 #include "base/task.h"
14 #include "chrome/browser/extensions/settings/failing_settings_storage.h"
14 #include "chrome/browser/extensions/settings/settings_frontend.h" 15 #include "chrome/browser/extensions/settings/settings_frontend.h"
15 #include "chrome/browser/extensions/settings/settings_storage_cache.h" 16 #include "chrome/browser/extensions/settings/settings_storage_cache.h"
17 #include "chrome/browser/extensions/settings/settings_storage_factory.h"
16 #include "chrome/browser/extensions/settings/settings_sync_util.h" 18 #include "chrome/browser/extensions/settings/settings_sync_util.h"
19 #include "chrome/browser/extensions/settings/settings_test_util.h"
17 #include "chrome/browser/extensions/settings/syncable_settings_storage.h" 20 #include "chrome/browser/extensions/settings/syncable_settings_storage.h"
18 #include "chrome/browser/extensions/settings/settings_test_util.h" 21 #include "chrome/browser/extensions/settings/testing_settings_storage.h"
19 #include "chrome/browser/sync/api/sync_change_processor.h" 22 #include "chrome/browser/sync/api/sync_change_processor.h"
20 #include "content/test/test_browser_thread.h" 23 #include "content/test/test_browser_thread.h"
21 24
22 namespace extensions { 25 // TODO(kalman): Integration tests for sync.
23 26
24 using content::BrowserThread; 27 using content::BrowserThread;
25 28
26 // TODO(kalman): Integration tests for sync. 29 namespace extensions {
27 30
28 using namespace settings_test_util; 31 using namespace settings_test_util;
29 32
30 namespace { 33 namespace {
31 34
32 // Gets the pretty-printed JSON for a value. 35 // Gets the pretty-printed JSON for a value.
33 static std::string GetJson(const Value& value) { 36 static std::string GetJson(const Value& value) {
34 std::string json; 37 std::string json;
35 base::JSONWriter::Write(&value, true, &json); 38 base::JSONWriter::Write(&value, true, &json);
36 return json; 39 return json;
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
70 "Expected: " << GetJson(expected) << 73 "Expected: " << GetJson(expected) <<
71 ", actual has error: " << actual.error(); 74 ", actual has error: " << actual.error();
72 } 75 }
73 return ValuesEq(_1, _2, &expected, &actual.settings()); 76 return ValuesEq(_1, _2, &expected, &actual.settings());
74 } 77 }
75 78
76 // SyncChangeProcessor which just records the changes made, accessed after 79 // SyncChangeProcessor which just records the changes made, accessed after
77 // being converted to the more useful SettingSyncData via changes(). 80 // being converted to the more useful SettingSyncData via changes().
78 class MockSyncChangeProcessor : public SyncChangeProcessor { 81 class MockSyncChangeProcessor : public SyncChangeProcessor {
79 public: 82 public:
83 MockSyncChangeProcessor() : fail_all_requests_(false) {}
84
85 // SyncChangeProcessor implementation.
80 virtual SyncError ProcessSyncChanges( 86 virtual SyncError ProcessSyncChanges(
81 const tracked_objects::Location& from_here, 87 const tracked_objects::Location& from_here,
82 const SyncChangeList& change_list) OVERRIDE { 88 const SyncChangeList& change_list) OVERRIDE {
89 if (fail_all_requests_) {
90 return SyncError(
91 FROM_HERE,
92 "MockSyncChangeProcessor: configured to fail",
93 change_list[0].sync_data().GetDataType());
94 }
83 for (SyncChangeList::const_iterator it = change_list.begin(); 95 for (SyncChangeList::const_iterator it = change_list.begin();
84 it != change_list.end(); ++it) { 96 it != change_list.end(); ++it) {
85 changes_.push_back(SettingSyncData(*it)); 97 changes_.push_back(SettingSyncData(*it));
86 } 98 }
87 return SyncError(); 99 return SyncError();
88 } 100 }
89 101
102 // Mock methods.
103
90 const SettingSyncDataList& changes() { return changes_; } 104 const SettingSyncDataList& changes() { return changes_; }
91 105
92 void ClearChanges() { 106 void ClearChanges() {
93 changes_.clear(); 107 changes_.clear();
94 } 108 }
95 109
110 void SetFailAllRequests(bool fail_all_requests) {
111 fail_all_requests_ = fail_all_requests;
112 }
113
96 // Returns the only change for a given extension setting. If there is not 114 // Returns the only change for a given extension setting. If there is not
97 // exactly 1 change for that key, a test assertion will fail. 115 // exactly 1 change for that key, a test assertion will fail.
98 SettingSyncData GetOnlyChange( 116 SettingSyncData GetOnlyChange(
99 const std::string& extension_id, const std::string& key) { 117 const std::string& extension_id, const std::string& key) {
100 SettingSyncDataList matching_changes; 118 SettingSyncDataList matching_changes;
101 for (SettingSyncDataList::iterator it = changes_.begin(); 119 for (SettingSyncDataList::iterator it = changes_.begin();
102 it != changes_.end(); ++it) { 120 it != changes_.end(); ++it) {
103 if (it->extension_id() == extension_id && it->key() == key) { 121 if (it->extension_id() == extension_id && it->key() == key) {
104 matching_changes.push_back(*it); 122 matching_changes.push_back(*it);
105 } 123 }
106 } 124 }
107 if (matching_changes.empty()) { 125 if (matching_changes.empty()) {
108 ADD_FAILURE() << "No matching changes for " << extension_id << "/" << 126 ADD_FAILURE() << "No matching changes for " << extension_id << "/" <<
109 key << " (out of " << changes_.size() << ")"; 127 key << " (out of " << changes_.size() << ")";
110 return SettingSyncData( 128 return SettingSyncData(
111 SyncChange::ACTION_INVALID, "", "", new DictionaryValue()); 129 SyncChange::ACTION_INVALID, "", "", new DictionaryValue());
112 } 130 }
113 if (matching_changes.size() != 1u) { 131 if (matching_changes.size() != 1u) {
114 ADD_FAILURE() << matching_changes.size() << " matching changes for " << 132 ADD_FAILURE() << matching_changes.size() << " matching changes for " <<
115 extension_id << "/" << key << " (out of " << changes_.size() << ")"; 133 extension_id << "/" << key << " (out of " << changes_.size() << ")";
116 } 134 }
117 return matching_changes[0]; 135 return matching_changes[0];
118 } 136 }
119 137
120 private: 138 private:
121 SettingSyncDataList changes_; 139 SettingSyncDataList changes_;
140 bool fail_all_requests_;
141 };
142
143 // SettingsStorageFactory which always returns TestingSettingsStorage objects,
144 // and allows individually created objects to be returned.
145 class TestingSettingsStorageFactory : public SettingsStorageFactory {
146 public:
147 TestingSettingsStorage* GetExisting(const std::string& extension_id) {
148 DCHECK(created_.count(extension_id));
149 return created_[extension_id];
150 }
151
152 // SettingsStorageFactory implementation.
153 virtual SettingsStorage* Create(
154 const FilePath& base_path, const std::string& extension_id) OVERRIDE {
155 TestingSettingsStorage* new_storage = new TestingSettingsStorage();
156 DCHECK(!created_.count(extension_id));
157 created_[extension_id] = new_storage;
158 return new_storage;
159 }
160
161 private:
162 // None of these storage areas are owned by this factory, so care must be
163 // taken when calling GetExisting.
164 std::map<std::string, TestingSettingsStorage*> created_;
122 }; 165 };
123 166
124 void AssignSettingsService(SyncableService** dst, SyncableService* src) { 167 void AssignSettingsService(SyncableService** dst, SyncableService* src) {
125 *dst = src; 168 *dst = src;
126 } 169 }
127 170
128 } // namespace 171 } // namespace
129 172
130 class ExtensionSettingsSyncTest : public testing::Test { 173 class ExtensionSettingsSyncTest : public testing::Test {
131 public: 174 public:
132 ExtensionSettingsSyncTest() 175 ExtensionSettingsSyncTest()
133 : ui_thread_(BrowserThread::UI, MessageLoop::current()), 176 : ui_thread_(BrowserThread::UI, MessageLoop::current()),
134 file_thread_(BrowserThread::FILE, MessageLoop::current()) {} 177 file_thread_(BrowserThread::FILE, MessageLoop::current()) {}
135 178
136 virtual void SetUp() OVERRIDE { 179 virtual void SetUp() OVERRIDE {
137 ASSERT_TRUE(temp_dir_.CreateUniqueTempDir()); 180 ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
138 profile_.reset(new MockProfile(temp_dir_.path())); 181 profile_.reset(new MockProfile(temp_dir_.path()));
139 frontend_.reset(SettingsFrontend::Create(profile_.get())); 182 storage_factory_ =
183 new ScopedSettingsStorageFactory(new SettingsLeveldbStorage::Factory());
184 frontend_.reset(SettingsFrontend::Create(storage_factory_, profile_.get()));
140 } 185 }
141 186
142 virtual void TearDown() OVERRIDE { 187 virtual void TearDown() OVERRIDE {
143 frontend_.reset(); 188 frontend_.reset();
144 profile_.reset(); 189 profile_.reset();
145 } 190 }
146 191
147 protected: 192 protected:
148 // Adds a record of an extension or app to the extension service, then returns 193 // Adds a record of an extension or app to the extension service, then returns
149 // its storage area. 194 // its storage area.
(...skipping 29 matching lines...) Expand all
179 224
180 // Need these so that the DCHECKs for running on FILE or UI threads pass. 225 // Need these so that the DCHECKs for running on FILE or UI threads pass.
181 MessageLoop message_loop_; 226 MessageLoop message_loop_;
182 content::TestBrowserThread ui_thread_; 227 content::TestBrowserThread ui_thread_;
183 content::TestBrowserThread file_thread_; 228 content::TestBrowserThread file_thread_;
184 229
185 ScopedTempDir temp_dir_; 230 ScopedTempDir temp_dir_;
186 MockSyncChangeProcessor sync_; 231 MockSyncChangeProcessor sync_;
187 scoped_ptr<MockProfile> profile_; 232 scoped_ptr<MockProfile> profile_;
188 scoped_ptr<SettingsFrontend> frontend_; 233 scoped_ptr<SettingsFrontend> frontend_;
234
235 // Owned by |frontend_|.
236 ScopedSettingsStorageFactory* storage_factory_;
189 }; 237 };
190 238
191 // Get a semblance of coverage for both EXTENSION_SETTINGS and APP_SETTINGS 239 // Get a semblance of coverage for both EXTENSION_SETTINGS and APP_SETTINGS
192 // sync by roughly alternative which one to test. 240 // sync by roughly alternative which one to test.
193 241
194 TEST_F(ExtensionSettingsSyncTest, NoDataDoesNotInvokeSync) { 242 TEST_F(ExtensionSettingsSyncTest, NoDataDoesNotInvokeSync) {
195 syncable::ModelType model_type = syncable::EXTENSION_SETTINGS; 243 syncable::ModelType model_type = syncable::EXTENSION_SETTINGS;
196 Extension::Type type = Extension::TYPE_EXTENSION; 244 Extension::Type type = Extension::TYPE_EXTENSION;
197 245
198 ASSERT_EQ(0u, GetAllSyncData(model_type).size()); 246 ASSERT_EQ(0u, GetAllSyncData(model_type).size());
(...skipping 381 matching lines...) Expand 10 before | Expand all | Expand 10 after
580 sync_data.push_back(settings_sync_util::CreateData( 628 sync_data.push_back(settings_sync_util::CreateData(
581 "s2", "bar", value2)); 629 "s2", "bar", value2));
582 630
583 GetSyncableService(syncable::APP_SETTINGS)-> 631 GetSyncableService(syncable::APP_SETTINGS)->
584 MergeDataAndStartSyncing(syncable::APP_SETTINGS, sync_data, &sync_); 632 MergeDataAndStartSyncing(syncable::APP_SETTINGS, sync_data, &sync_);
585 GetSyncableService(syncable::APP_SETTINGS)-> 633 GetSyncableService(syncable::APP_SETTINGS)->
586 StopSyncing(syncable::APP_SETTINGS); 634 StopSyncing(syncable::APP_SETTINGS);
587 ASSERT_EQ(0u, sync_.changes().size()); 635 ASSERT_EQ(0u, sync_.changes().size());
588 } 636 }
589 637
638 TEST_F(ExtensionSettingsSyncTest, FailingStartSyncingDisablesSync) {
639 syncable::ModelType model_type = syncable::EXTENSION_SETTINGS;
640 Extension::Type type = Extension::TYPE_EXTENSION;
641
642 StringValue fooValue("fooValue");
643 StringValue barValue("barValue");
644
645 // There is a bit of a convoluted method to get storage areas that can fail;
646 // hand out TestingSettingsStorage object then toggle them failing/succeeding
647 // as necessary.
648 TestingSettingsStorageFactory* testing_factory =
649 new TestingSettingsStorageFactory();
650 storage_factory_->Reset(testing_factory);
651
652 SettingsStorage* good = AddExtensionAndGetStorage("good", type);
653 SettingsStorage* bad = AddExtensionAndGetStorage("bad", type);
654
655 // Make bad fail for incoming sync changes.
656 testing_factory->GetExisting("bad")->SetFailAllRequests(true);
657 {
658 SyncDataList sync_data;
659 sync_data.push_back(
660 settings_sync_util::CreateData("good", "foo", fooValue));
661 sync_data.push_back(
662 settings_sync_util::CreateData("bad", "foo", fooValue));
663 GetSyncableService(model_type)->MergeDataAndStartSyncing(
664 model_type, sync_data, &sync_);
665 }
666 testing_factory->GetExisting("bad")->SetFailAllRequests(false);
667
668 {
669 DictionaryValue dict;
670 dict.Set("foo", fooValue.DeepCopy());
671 EXPECT_PRED_FORMAT2(SettingsEq, dict, good->Get());
672 }
673 {
674 DictionaryValue dict;
675 EXPECT_PRED_FORMAT2(SettingsEq, dict, bad->Get());
676 }
677
678 // Changes made to good should be sent to sync, changes from bad shouldn't.
679 sync_.ClearChanges();
680 good->Set("bar", barValue);
681 bad->Set("bar", barValue);
682
683 EXPECT_EQ(
684 SyncChange::ACTION_ADD,
685 sync_.GetOnlyChange("good", "bar").change_type());
686 EXPECT_EQ(1u, sync_.changes().size());
687
688 {
689 DictionaryValue dict;
690 dict.Set("foo", fooValue.DeepCopy());
691 dict.Set("bar", barValue.DeepCopy());
692 EXPECT_PRED_FORMAT2(SettingsEq, dict, good->Get());
693 }
694 {
695 DictionaryValue dict;
696 dict.Set("bar", barValue.DeepCopy());
697 EXPECT_PRED_FORMAT2(SettingsEq, dict, bad->Get());
698 }
699
700 // Changes received from sync should go to good but not bad (even when it's
701 // not failing).
702 {
703 SyncChangeList change_list;
704 change_list.push_back(
705 settings_sync_util::CreateUpdate("good", "foo", barValue));
706 // (Sending UPDATE here even though it's adding, since that's what the state
707 // of sync is. In any case, it won't work.)
708 change_list.push_back(
709 settings_sync_util::CreateUpdate("bad", "foo", barValue));
710 GetSyncableService(model_type)->ProcessSyncChanges(FROM_HERE, change_list);
711 }
712
713 {
714 DictionaryValue dict;
715 dict.Set("foo", barValue.DeepCopy());
716 dict.Set("bar", barValue.DeepCopy());
717 EXPECT_PRED_FORMAT2(SettingsEq, dict, good->Get());
718 }
719 {
720 DictionaryValue dict;
721 dict.Set("bar", barValue.DeepCopy());
722 EXPECT_PRED_FORMAT2(SettingsEq, dict, bad->Get());
723 }
724
725 // Changes made to bad still shouldn't go to sync, even though it didn't fail
726 // last time.
727 sync_.ClearChanges();
728 good->Set("bar", fooValue);
729 bad->Set("bar", fooValue);
730
731 EXPECT_EQ(
732 SyncChange::ACTION_UPDATE,
733 sync_.GetOnlyChange("good", "bar").change_type());
734 EXPECT_EQ(1u, sync_.changes().size());
735
736 {
737 DictionaryValue dict;
738 dict.Set("foo", barValue.DeepCopy());
739 dict.Set("bar", fooValue.DeepCopy());
740 EXPECT_PRED_FORMAT2(SettingsEq, dict, good->Get());
741 }
742 {
743 DictionaryValue dict;
744 dict.Set("bar", fooValue.DeepCopy());
745 EXPECT_PRED_FORMAT2(SettingsEq, dict, bad->Get());
746 }
747
748 // Failing ProcessSyncChanges shouldn't go to the storage.
749 testing_factory->GetExisting("bad")->SetFailAllRequests(true);
750 {
751 SyncChangeList change_list;
752 change_list.push_back(
753 settings_sync_util::CreateUpdate("good", "foo", fooValue));
754 // (Ditto.)
755 change_list.push_back(
756 settings_sync_util::CreateUpdate("bad", "foo", fooValue));
757 GetSyncableService(model_type)->ProcessSyncChanges(FROM_HERE, change_list);
758 }
759 testing_factory->GetExisting("bad")->SetFailAllRequests(false);
760
761 {
762 DictionaryValue dict;
763 dict.Set("foo", fooValue.DeepCopy());
764 dict.Set("bar", fooValue.DeepCopy());
765 EXPECT_PRED_FORMAT2(SettingsEq, dict, good->Get());
766 }
767 {
768 DictionaryValue dict;
769 dict.Set("bar", fooValue.DeepCopy());
770 EXPECT_PRED_FORMAT2(SettingsEq, dict, bad->Get());
771 }
772
773 // Restarting sync should make bad start syncing again.
774 sync_.ClearChanges();
775 GetSyncableService(model_type)->StopSyncing(model_type);
776 GetSyncableService(model_type)->MergeDataAndStartSyncing(
777 model_type, SyncDataList(), &sync_);
778
779 // Local settings will have been pushed to sync, since it's empty (in this
780 // test; presumably it wouldn't be live, since we've been getting changes).
781 EXPECT_EQ(
782 SyncChange::ACTION_ADD,
783 sync_.GetOnlyChange("good", "foo").change_type());
784 EXPECT_EQ(
785 SyncChange::ACTION_ADD,
786 sync_.GetOnlyChange("good", "bar").change_type());
787 EXPECT_EQ(
788 SyncChange::ACTION_ADD,
789 sync_.GetOnlyChange("bad", "bar").change_type());
790 EXPECT_EQ(3u, sync_.changes().size());
791
792 // Live local changes now get pushed, too.
793 sync_.ClearChanges();
794 good->Set("bar", barValue);
795 bad->Set("bar", barValue);
796
797 EXPECT_EQ(
798 SyncChange::ACTION_UPDATE,
799 sync_.GetOnlyChange("good", "bar").change_type());
800 EXPECT_EQ(
801 SyncChange::ACTION_UPDATE,
802 sync_.GetOnlyChange("bad", "bar").change_type());
803 EXPECT_EQ(2u, sync_.changes().size());
804
805 // And ProcessSyncChanges work, too.
806 {
807 SyncChangeList change_list;
808 change_list.push_back(
809 settings_sync_util::CreateUpdate("good", "bar", fooValue));
810 change_list.push_back(
811 settings_sync_util::CreateUpdate("bad", "bar", fooValue));
812 GetSyncableService(model_type)->ProcessSyncChanges(FROM_HERE, change_list);
813 }
814
815 {
816 DictionaryValue dict;
817 dict.Set("foo", fooValue.DeepCopy());
818 dict.Set("bar", fooValue.DeepCopy());
819 EXPECT_PRED_FORMAT2(SettingsEq, dict, good->Get());
820 }
821 {
822 DictionaryValue dict;
823 dict.Set("bar", fooValue.DeepCopy());
824 EXPECT_PRED_FORMAT2(SettingsEq, dict, bad->Get());
825 }
826 }
827
828 TEST_F(ExtensionSettingsSyncTest, FailingProcessChangesDisablesSync) {
829 // The test above tests a failing ProcessSyncChanges too, but here test with
830 // an initially passing MergeDataAndStartSyncing.
831 syncable::ModelType model_type = syncable::APP_SETTINGS;
832 Extension::Type type = Extension::TYPE_PACKAGED_APP;
833
834 StringValue fooValue("fooValue");
835 StringValue barValue("barValue");
836
837 TestingSettingsStorageFactory* testing_factory =
838 new TestingSettingsStorageFactory();
839 storage_factory_->Reset(testing_factory);
840
841 SettingsStorage* good = AddExtensionAndGetStorage("good", type);
842 SettingsStorage* bad = AddExtensionAndGetStorage("bad", type);
843
844 // Unlike before, initially succeeding MergeDataAndStartSyncing.
845 {
846 SyncDataList sync_data;
847 sync_data.push_back(
848 settings_sync_util::CreateData("good", "foo", fooValue));
849 sync_data.push_back(
850 settings_sync_util::CreateData("bad", "foo", fooValue));
851 GetSyncableService(model_type)->MergeDataAndStartSyncing(
852 model_type, sync_data, &sync_);
853 }
854
855 EXPECT_EQ(0u, sync_.changes().size());
856
857 {
858 DictionaryValue dict;
859 dict.Set("foo", fooValue.DeepCopy());
860 EXPECT_PRED_FORMAT2(SettingsEq, dict, good->Get());
861 }
862 {
863 DictionaryValue dict;
864 dict.Set("foo", fooValue.DeepCopy());
865 EXPECT_PRED_FORMAT2(SettingsEq, dict, bad->Get());
866 }
867
868 // Now fail ProcessSyncChanges for bad.
869 testing_factory->GetExisting("bad")->SetFailAllRequests(true);
870 {
871 SyncChangeList change_list;
872 change_list.push_back(
873 settings_sync_util::CreateAdd("good", "bar", barValue));
874 change_list.push_back(
875 settings_sync_util::CreateAdd("bad", "bar", barValue));
876 GetSyncableService(model_type)->ProcessSyncChanges(FROM_HERE, change_list);
877 }
878 testing_factory->GetExisting("bad")->SetFailAllRequests(false);
879
880 {
881 DictionaryValue dict;
882 dict.Set("foo", fooValue.DeepCopy());
883 dict.Set("bar", barValue.DeepCopy());
884 EXPECT_PRED_FORMAT2(SettingsEq, dict, good->Get());
885 }
886 {
887 DictionaryValue dict;
888 dict.Set("foo", fooValue.DeepCopy());
889 EXPECT_PRED_FORMAT2(SettingsEq, dict, bad->Get());
890 }
891
892 // No more changes sent to sync for bad.
893 sync_.ClearChanges();
894 good->Set("foo", barValue);
895 bad->Set("foo", barValue);
896
897 EXPECT_EQ(
898 SyncChange::ACTION_UPDATE,
899 sync_.GetOnlyChange("good", "foo").change_type());
900 EXPECT_EQ(1u, sync_.changes().size());
901
902 // No more changes received from sync should go to bad.
903 {
904 SyncChangeList change_list;
905 change_list.push_back(
906 settings_sync_util::CreateAdd("good", "foo", fooValue));
907 change_list.push_back(
908 settings_sync_util::CreateAdd("bad", "foo", fooValue));
909 GetSyncableService(model_type)->ProcessSyncChanges(FROM_HERE, change_list);
910 }
911
912 {
913 DictionaryValue dict;
914 dict.Set("foo", fooValue.DeepCopy());
915 dict.Set("bar", barValue.DeepCopy());
916 EXPECT_PRED_FORMAT2(SettingsEq, dict, good->Get());
917 }
918 {
919 DictionaryValue dict;
920 dict.Set("foo", barValue.DeepCopy());
921 EXPECT_PRED_FORMAT2(SettingsEq, dict, bad->Get());
922 }
923 }
924
925 TEST_F(ExtensionSettingsSyncTest, FailingGetAllSyncDataDoesntStopSync) {
926 syncable::ModelType model_type = syncable::EXTENSION_SETTINGS;
927 Extension::Type type = Extension::TYPE_EXTENSION;
928
929 StringValue fooValue("fooValue");
930 StringValue barValue("barValue");
931
932 TestingSettingsStorageFactory* testing_factory =
933 new TestingSettingsStorageFactory();
934 storage_factory_->Reset(testing_factory);
935
936 SettingsStorage* good = AddExtensionAndGetStorage("good", type);
937 SettingsStorage* bad = AddExtensionAndGetStorage("bad", type);
938
939 good->Set("foo", fooValue);
940 bad->Set("foo", fooValue);
941
942 // Even though bad will fail to get all sync data, sync data should still
943 // include that from good.
944 testing_factory->GetExisting("bad")->SetFailAllRequests(true);
945 {
946 SyncDataList all_sync_data =
947 GetSyncableService(model_type)->GetAllSyncData(model_type);
948 EXPECT_EQ(1u, all_sync_data.size());
949 EXPECT_EQ("good/foo", all_sync_data[0].GetTag());
950 }
951 testing_factory->GetExisting("bad")->SetFailAllRequests(false);
952
953 // Sync shouldn't be disabled for good (nor bad -- but this is unimportant).
954 GetSyncableService(model_type)->MergeDataAndStartSyncing(
955 model_type, SyncDataList(), &sync_);
956
957 EXPECT_EQ(
958 SyncChange::ACTION_ADD,
959 sync_.GetOnlyChange("good", "foo").change_type());
960 EXPECT_EQ(
961 SyncChange::ACTION_ADD,
962 sync_.GetOnlyChange("bad", "foo").change_type());
963 EXPECT_EQ(2u, sync_.changes().size());
964
965 sync_.ClearChanges();
966 good->Set("bar", barValue);
967 bad->Set("bar", barValue);
968
969 EXPECT_EQ(
970 SyncChange::ACTION_ADD,
971 sync_.GetOnlyChange("good", "bar").change_type());
972 EXPECT_EQ(
973 SyncChange::ACTION_ADD,
974 sync_.GetOnlyChange("bad", "bar").change_type());
975 EXPECT_EQ(2u, sync_.changes().size());
976 }
977
978 TEST_F(ExtensionSettingsSyncTest, FailureToReadChangesToPushDisablesSync) {
979 syncable::ModelType model_type = syncable::APP_SETTINGS;
980 Extension::Type type = Extension::TYPE_PACKAGED_APP;
981
982 StringValue fooValue("fooValue");
983 StringValue barValue("barValue");
984
985 TestingSettingsStorageFactory* testing_factory =
986 new TestingSettingsStorageFactory();
987 storage_factory_->Reset(testing_factory);
988
989 SettingsStorage* good = AddExtensionAndGetStorage("good", type);
990 SettingsStorage* bad = AddExtensionAndGetStorage("bad", type);
991
992 good->Set("foo", fooValue);
993 bad->Set("foo", fooValue);
994
995 // good will successfully push foo:fooValue to sync, but bad will fail to
996 // get them so won't.
997 testing_factory->GetExisting("bad")->SetFailAllRequests(true);
998 GetSyncableService(model_type)->MergeDataAndStartSyncing(
999 model_type, SyncDataList(), &sync_);
1000 testing_factory->GetExisting("bad")->SetFailAllRequests(false);
1001
1002 EXPECT_EQ(
1003 SyncChange::ACTION_ADD,
1004 sync_.GetOnlyChange("good", "foo").change_type());
1005 EXPECT_EQ(1u, sync_.changes().size());
1006
1007 // bad should now be disabled for sync.
1008 sync_.ClearChanges();
1009 good->Set("bar", barValue);
1010 bad->Set("bar", barValue);
1011
1012 EXPECT_EQ(
1013 SyncChange::ACTION_ADD,
1014 sync_.GetOnlyChange("good", "bar").change_type());
1015 EXPECT_EQ(1u, sync_.changes().size());
1016
1017 {
1018 SyncChangeList change_list;
1019 change_list.push_back(
1020 settings_sync_util::CreateUpdate("good", "foo", barValue));
1021 // (Sending ADD here even though it's updating, since that's what the state
1022 // of sync is. In any case, it won't work.)
1023 change_list.push_back(
1024 settings_sync_util::CreateAdd("bad", "foo", barValue));
1025 GetSyncableService(model_type)->ProcessSyncChanges(FROM_HERE, change_list);
1026 }
1027
1028 {
1029 DictionaryValue dict;
1030 dict.Set("foo", barValue.DeepCopy());
1031 dict.Set("bar", barValue.DeepCopy());
1032 EXPECT_PRED_FORMAT2(SettingsEq, dict, good->Get());
1033 }
1034 {
1035 DictionaryValue dict;
1036 dict.Set("foo", fooValue.DeepCopy());
1037 dict.Set("bar", barValue.DeepCopy());
1038 EXPECT_PRED_FORMAT2(SettingsEq, dict, bad->Get());
1039 }
1040
1041 // Re-enabling sync without failing should cause the local changes from bad
1042 // to be pushed to sync successfully, as should future changes to bad.
1043 sync_.ClearChanges();
1044 GetSyncableService(model_type)->StopSyncing(model_type);
1045 GetSyncableService(model_type)->MergeDataAndStartSyncing(
1046 model_type, SyncDataList(), &sync_);
1047
1048 EXPECT_EQ(
1049 SyncChange::ACTION_ADD,
1050 sync_.GetOnlyChange("good", "foo").change_type());
1051 EXPECT_EQ(
1052 SyncChange::ACTION_ADD,
1053 sync_.GetOnlyChange("good", "bar").change_type());
1054 EXPECT_EQ(
1055 SyncChange::ACTION_ADD,
1056 sync_.GetOnlyChange("bad", "foo").change_type());
1057 EXPECT_EQ(
1058 SyncChange::ACTION_ADD,
1059 sync_.GetOnlyChange("bad", "bar").change_type());
1060 EXPECT_EQ(4u, sync_.changes().size());
1061
1062 sync_.ClearChanges();
1063 good->Set("bar", fooValue);
1064 bad->Set("bar", fooValue);
1065
1066 EXPECT_EQ(
1067 SyncChange::ACTION_UPDATE,
1068 sync_.GetOnlyChange("good", "bar").change_type());
1069 EXPECT_EQ(
1070 SyncChange::ACTION_UPDATE,
1071 sync_.GetOnlyChange("good", "bar").change_type());
1072 EXPECT_EQ(2u, sync_.changes().size());
1073 }
1074
1075 TEST_F(ExtensionSettingsSyncTest, FailureToPushLocalStateDisablesSync) {
1076 syncable::ModelType model_type = syncable::EXTENSION_SETTINGS;
1077 Extension::Type type = Extension::TYPE_EXTENSION;
1078
1079 StringValue fooValue("fooValue");
1080 StringValue barValue("barValue");
1081
1082 TestingSettingsStorageFactory* testing_factory =
1083 new TestingSettingsStorageFactory();
1084 storage_factory_->Reset(testing_factory);
1085
1086 SettingsStorage* good = AddExtensionAndGetStorage("good", type);
1087 SettingsStorage* bad = AddExtensionAndGetStorage("bad", type);
1088
1089 // Only set bad; setting good will cause it to fail below.
1090 bad->Set("foo", fooValue);
1091
1092 sync_.SetFailAllRequests(true);
1093 GetSyncableService(model_type)->MergeDataAndStartSyncing(
1094 model_type, SyncDataList(), &sync_);
1095 sync_.SetFailAllRequests(false);
1096
1097 // Changes from good will be send to sync, changes from bad won't.
1098 sync_.ClearChanges();
1099 good->Set("foo", barValue);
1100 bad->Set("foo", barValue);
1101
1102 EXPECT_EQ(
1103 SyncChange::ACTION_ADD,
1104 sync_.GetOnlyChange("good", "foo").change_type());
1105 EXPECT_EQ(1u, sync_.changes().size());
1106
1107 // Changes from sync will be sent to good, not to bad.
1108 {
1109 SyncChangeList change_list;
1110 change_list.push_back(
1111 settings_sync_util::CreateAdd("good", "bar", barValue));
1112 change_list.push_back(
1113 settings_sync_util::CreateAdd("bad", "bar", barValue));
1114 GetSyncableService(model_type)->ProcessSyncChanges(FROM_HERE, change_list);
1115 }
1116
1117 {
1118 DictionaryValue dict;
1119 dict.Set("foo", barValue.DeepCopy());
1120 dict.Set("bar", barValue.DeepCopy());
1121 EXPECT_PRED_FORMAT2(SettingsEq, dict, good->Get());
1122 }
1123 {
1124 DictionaryValue dict;
1125 dict.Set("foo", barValue.DeepCopy());
1126 EXPECT_PRED_FORMAT2(SettingsEq, dict, bad->Get());
1127 }
1128
1129 // Restarting sync makes everything work again.
1130 sync_.ClearChanges();
1131 GetSyncableService(model_type)->StopSyncing(model_type);
1132 GetSyncableService(model_type)->MergeDataAndStartSyncing(
1133 model_type, SyncDataList(), &sync_);
1134
1135 EXPECT_EQ(
1136 SyncChange::ACTION_ADD,
1137 sync_.GetOnlyChange("good", "foo").change_type());
1138 EXPECT_EQ(
1139 SyncChange::ACTION_ADD,
1140 sync_.GetOnlyChange("good", "bar").change_type());
1141 EXPECT_EQ(
1142 SyncChange::ACTION_ADD,
1143 sync_.GetOnlyChange("bad", "foo").change_type());
1144 EXPECT_EQ(3u, sync_.changes().size());
1145
1146 sync_.ClearChanges();
1147 good->Set("foo", fooValue);
1148 bad->Set("foo", fooValue);
1149
1150 EXPECT_EQ(
1151 SyncChange::ACTION_UPDATE,
1152 sync_.GetOnlyChange("good", "foo").change_type());
1153 EXPECT_EQ(
1154 SyncChange::ACTION_UPDATE,
1155 sync_.GetOnlyChange("good", "foo").change_type());
1156 EXPECT_EQ(2u, sync_.changes().size());
1157 }
1158
1159 TEST_F(ExtensionSettingsSyncTest, FailureToPushLocalChangeDisablesSync) {
1160 syncable::ModelType model_type = syncable::EXTENSION_SETTINGS;
1161 Extension::Type type = Extension::TYPE_EXTENSION;
1162
1163 StringValue fooValue("fooValue");
1164 StringValue barValue("barValue");
1165
1166 TestingSettingsStorageFactory* testing_factory =
1167 new TestingSettingsStorageFactory();
1168 storage_factory_->Reset(testing_factory);
1169
1170 SettingsStorage* good = AddExtensionAndGetStorage("good", type);
1171 SettingsStorage* bad = AddExtensionAndGetStorage("bad", type);
1172
1173 GetSyncableService(model_type)->MergeDataAndStartSyncing(
1174 model_type, SyncDataList(), &sync_);
1175
1176 // bad will fail to send changes.
1177 good->Set("foo", fooValue);
1178 sync_.SetFailAllRequests(true);
1179 bad->Set("foo", fooValue);
1180 sync_.SetFailAllRequests(false);
1181
1182 EXPECT_EQ(
1183 SyncChange::ACTION_ADD,
1184 sync_.GetOnlyChange("good", "foo").change_type());
1185 EXPECT_EQ(1u, sync_.changes().size());
1186
1187 // No further changes should be sent from bad.
1188 sync_.ClearChanges();
1189 good->Set("foo", barValue);
1190 bad->Set("foo", barValue);
1191
1192 EXPECT_EQ(
1193 SyncChange::ACTION_UPDATE,
1194 sync_.GetOnlyChange("good", "foo").change_type());
1195 EXPECT_EQ(1u, sync_.changes().size());
1196
1197 // Changes from sync will be sent to good, not to bad.
1198 {
1199 SyncChangeList change_list;
1200 change_list.push_back(
1201 settings_sync_util::CreateAdd("good", "bar", barValue));
1202 change_list.push_back(
1203 settings_sync_util::CreateAdd("bad", "bar", barValue));
1204 GetSyncableService(model_type)->ProcessSyncChanges(FROM_HERE, change_list);
1205 }
1206
1207 {
1208 DictionaryValue dict;
1209 dict.Set("foo", barValue.DeepCopy());
1210 dict.Set("bar", barValue.DeepCopy());
1211 EXPECT_PRED_FORMAT2(SettingsEq, dict, good->Get());
1212 }
1213 {
1214 DictionaryValue dict;
1215 dict.Set("foo", barValue.DeepCopy());
1216 EXPECT_PRED_FORMAT2(SettingsEq, dict, bad->Get());
1217 }
1218
1219 // Restarting sync makes everything work again.
1220 sync_.ClearChanges();
1221 GetSyncableService(model_type)->StopSyncing(model_type);
1222 GetSyncableService(model_type)->MergeDataAndStartSyncing(
1223 model_type, SyncDataList(), &sync_);
1224
1225 EXPECT_EQ(
1226 SyncChange::ACTION_ADD,
1227 sync_.GetOnlyChange("good", "foo").change_type());
1228 EXPECT_EQ(
1229 SyncChange::ACTION_ADD,
1230 sync_.GetOnlyChange("good", "bar").change_type());
1231 EXPECT_EQ(
1232 SyncChange::ACTION_ADD,
1233 sync_.GetOnlyChange("bad", "foo").change_type());
1234 EXPECT_EQ(3u, sync_.changes().size());
1235
1236 sync_.ClearChanges();
1237 good->Set("foo", fooValue);
1238 bad->Set("foo", fooValue);
1239
1240 EXPECT_EQ(
1241 SyncChange::ACTION_UPDATE,
1242 sync_.GetOnlyChange("good", "foo").change_type());
1243 EXPECT_EQ(
1244 SyncChange::ACTION_UPDATE,
1245 sync_.GetOnlyChange("good", "foo").change_type());
1246 EXPECT_EQ(2u, sync_.changes().size());
1247 }
1248
590 } // namespace extensions 1249 } // namespace extensions
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698