OLD | NEW |
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 Loading... |
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 Loading... |
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 Loading... |
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 |
OLD | NEW |