OLD | NEW |
1 // Copyright 2016 The Chromium Authors. All rights reserved. | 1 // Copyright 2016 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 "base/macros.h" | 5 #include "base/macros.h" |
6 #include "base/memory/ptr_util.h" | 6 #include "base/memory/ptr_util.h" |
7 #include "base/threading/thread_task_runner_handle.h" | 7 #include "base/threading/thread_task_runner_handle.h" |
8 #include "chrome/browser/sync/chrome_sync_client.h" | 8 #include "chrome/browser/sync/chrome_sync_client.h" |
9 #include "chrome/browser/sync/profile_sync_service_factory.h" | 9 #include "chrome/browser/sync/profile_sync_service_factory.h" |
10 #include "chrome/browser/sync/test/integration/profile_sync_service_harness.h" | 10 #include "chrome/browser/sync/test/integration/profile_sync_service_harness.h" |
11 #include "chrome/browser/sync/test/integration/status_change_checker.h" | 11 #include "chrome/browser/sync/test/integration/status_change_checker.h" |
12 #include "chrome/browser/sync/test/integration/sync_integration_test_util.h" | 12 #include "chrome/browser/sync/test/integration/sync_integration_test_util.h" |
13 #include "chrome/browser/sync/test/integration/sync_test.h" | 13 #include "chrome/browser/sync/test/integration/sync_test.h" |
14 #include "components/browser_sync/browser/profile_sync_components_factory_impl.h
" | 14 #include "components/browser_sync/browser/profile_sync_components_factory_impl.h
" |
| 15 #include "components/browser_sync/browser/profile_sync_service.h" |
15 #include "components/sync/api/fake_model_type_service.h" | 16 #include "components/sync/api/fake_model_type_service.h" |
16 | 17 |
17 using browser_sync::ChromeSyncClient; | 18 using browser_sync::ChromeSyncClient; |
18 using syncer_v2::FakeModelTypeService; | 19 using syncer_v2::FakeModelTypeService; |
19 using syncer_v2::ModelTypeService; | 20 using syncer_v2::ModelTypeService; |
20 using syncer_v2::SharedModelTypeProcessor; | 21 using syncer_v2::SharedModelTypeProcessor; |
21 | 22 |
| 23 const char kKey1[] = "key1"; |
| 24 const char kValue1[] = "value1"; |
| 25 const char kValue2[] = "value2"; |
| 26 const char kResolutionValue[] = "RESOLVED"; |
| 27 |
22 // A ChromeSyncClient that provides a ModelTypeService for PREFERENCES. | 28 // A ChromeSyncClient that provides a ModelTypeService for PREFERENCES. |
23 class TestSyncClient : public ChromeSyncClient { | 29 class TestSyncClient : public ChromeSyncClient { |
24 public: | 30 public: |
25 TestSyncClient(Profile* profile, ModelTypeService* service) | 31 TestSyncClient(Profile* profile, ModelTypeService* service) |
26 : ChromeSyncClient(profile), service_(service) {} | 32 : ChromeSyncClient(profile), service_(service) {} |
27 | 33 |
28 base::WeakPtr<ModelTypeService> GetModelTypeServiceForType( | 34 base::WeakPtr<ModelTypeService> GetModelTypeServiceForType( |
29 syncer::ModelType type) override { | 35 syncer::ModelType type) override { |
30 return type == syncer::PREFERENCES | 36 return type == syncer::PREFERENCES |
31 ? service_->AsWeakPtr() | 37 ? service_->AsWeakPtr() |
(...skipping 23 matching lines...) Expand all Loading... |
55 std::move(metadata_changes), entity_changes); | 61 std::move(metadata_changes), entity_changes); |
56 NotifyObservers(); | 62 NotifyObservers(); |
57 return error; | 63 return error; |
58 } | 64 } |
59 | 65 |
60 void OnChangeProcessorSet() override { | 66 void OnChangeProcessorSet() override { |
61 change_processor()->OnMetadataLoaded(syncer::SyncError(), | 67 change_processor()->OnMetadataLoaded(syncer::SyncError(), |
62 db().CreateMetadataBatch()); | 68 db().CreateMetadataBatch()); |
63 } | 69 } |
64 | 70 |
| 71 syncer_v2::ConflictResolution ResolveConflict( |
| 72 const syncer_v2::EntityData& local_data, |
| 73 const syncer_v2::EntityData& remote_data) const override { |
| 74 return syncer_v2::ConflictResolution::UseNew( |
| 75 GenerateEntityData(local_data.non_unique_name, kResolutionValue)); |
| 76 } |
| 77 |
65 void AddObserver(Observer* observer) { observers_.insert(observer); } | 78 void AddObserver(Observer* observer) { observers_.insert(observer); } |
66 void RemoveObserver(Observer* observer) { observers_.erase(observer); } | 79 void RemoveObserver(Observer* observer) { observers_.erase(observer); } |
67 | 80 |
68 private: | 81 private: |
69 void NotifyObservers() { | 82 void NotifyObservers() { |
70 for (Observer* observer : observers_) { | 83 for (Observer* observer : observers_) { |
71 observer->OnApplySyncChanges(); | 84 observer->OnApplySyncChanges(); |
72 } | 85 } |
73 } | 86 } |
74 | 87 |
(...skipping 21 matching lines...) Expand all Loading... |
96 StartBlockingWait(); | 109 StartBlockingWait(); |
97 service_->RemoveObserver(this); | 110 service_->RemoveObserver(this); |
98 return !TimedOut(); | 111 return !TimedOut(); |
99 } | 112 } |
100 | 113 |
101 protected: | 114 protected: |
102 TestModelTypeService* const service_; | 115 TestModelTypeService* const service_; |
103 const std::string key_; | 116 const std::string key_; |
104 }; | 117 }; |
105 | 118 |
106 // Wait for a key to be present. | 119 // Wait for data for a key to have a certain value. |
107 class KeyPresentChecker : public KeyChecker { | 120 class DataChecker : public KeyChecker { |
108 public: | 121 public: |
109 KeyPresentChecker(TestModelTypeService* service, const std::string& key) | 122 DataChecker(TestModelTypeService* service, |
110 : KeyChecker(service, key) {} | 123 const std::string& key, |
111 ~KeyPresentChecker() override {} | 124 const std::string& value) |
| 125 : KeyChecker(service, key), value_(value) {} |
| 126 ~DataChecker() override {} |
112 | 127 |
113 bool IsExitConditionSatisfied() override { | 128 bool IsExitConditionSatisfied() override { |
114 return service_->db().HasData(key_); | 129 const auto& db = service_->db(); |
| 130 return db.HasData(key_) && db.GetValue(key_) == value_; |
115 } | 131 } |
116 | 132 |
117 std::string GetDebugMessage() const override { | 133 std::string GetDebugMessage() const override { |
118 return "Waiting for key '" + key_ + "' to be present."; | 134 return "Waiting for data for key '" + key_ + "' to be '" + value_ + "'."; |
119 } | 135 } |
| 136 |
| 137 private: |
| 138 const std::string value_; |
120 }; | 139 }; |
121 | 140 |
122 // Wait for a key to be absent. | 141 // Wait for data for a key to be absent. |
123 class KeyAbsentChecker : public KeyChecker { | 142 class DataAbsentChecker : public KeyChecker { |
124 public: | 143 public: |
125 KeyAbsentChecker(TestModelTypeService* service, const std::string& key) | 144 DataAbsentChecker(TestModelTypeService* service, const std::string& key) |
126 : KeyChecker(service, key) {} | 145 : KeyChecker(service, key) {} |
127 ~KeyAbsentChecker() override {} | 146 ~DataAbsentChecker() override {} |
128 | 147 |
129 bool IsExitConditionSatisfied() override { | 148 bool IsExitConditionSatisfied() override { |
130 return !service_->db().HasData(key_); | 149 return !service_->db().HasData(key_); |
131 } | 150 } |
132 | 151 |
133 std::string GetDebugMessage() const override { | 152 std::string GetDebugMessage() const override { |
134 return "Waiting for key '" + key_ + "' to be absent."; | 153 return "Waiting for data for key '" + key_ + "' to be absent."; |
135 } | 154 } |
136 }; | 155 }; |
137 | 156 |
| 157 // Wait for metadata for a key to be present. |
| 158 class MetadataPresentChecker : public KeyChecker { |
| 159 public: |
| 160 MetadataPresentChecker(TestModelTypeService* service, const std::string& key) |
| 161 : KeyChecker(service, key) {} |
| 162 ~MetadataPresentChecker() override {} |
| 163 |
| 164 bool IsExitConditionSatisfied() override { |
| 165 return service_->db().HasMetadata(key_); |
| 166 } |
| 167 |
| 168 std::string GetDebugMessage() const override { |
| 169 return "Waiting for metadata for key '" + key_ + "' to be present."; |
| 170 } |
| 171 }; |
| 172 |
| 173 // Wait for metadata for a key to be absent. |
| 174 class MetadataAbsentChecker : public KeyChecker { |
| 175 public: |
| 176 MetadataAbsentChecker(TestModelTypeService* service, const std::string& key) |
| 177 : KeyChecker(service, key) {} |
| 178 ~MetadataAbsentChecker() override {} |
| 179 |
| 180 bool IsExitConditionSatisfied() override { |
| 181 return !service_->db().HasMetadata(key_); |
| 182 } |
| 183 |
| 184 std::string GetDebugMessage() const override { |
| 185 return "Waiting for metadata for key '" + key_ + "' to be absent."; |
| 186 } |
| 187 }; |
| 188 |
138 class TwoClientUssSyncTest : public SyncTest { | 189 class TwoClientUssSyncTest : public SyncTest { |
139 public: | 190 public: |
140 TwoClientUssSyncTest() : SyncTest(TWO_CLIENT) { | 191 TwoClientUssSyncTest() : SyncTest(TWO_CLIENT) { |
141 DisableVerifier(); | 192 DisableVerifier(); |
142 sync_client_factory_ = base::Bind(&TwoClientUssSyncTest::CreateSyncClient, | 193 sync_client_factory_ = base::Bind(&TwoClientUssSyncTest::CreateSyncClient, |
143 base::Unretained(this)); | 194 base::Unretained(this)); |
144 ProfileSyncServiceFactory::SetSyncClientFactoryForTest( | 195 ProfileSyncServiceFactory::SetSyncClientFactoryForTest( |
145 &sync_client_factory_); | 196 &sync_client_factory_); |
146 ProfileSyncComponentsFactoryImpl::OverridePrefsForUssTest(true); | 197 ProfileSyncComponentsFactoryImpl::OverridePrefsForUssTest(true); |
147 } | 198 } |
(...skipping 21 matching lines...) Expand all Loading... |
169 clients_.push_back(client.get()); | 220 clients_.push_back(client.get()); |
170 services_.push_back(std::move(service)); | 221 services_.push_back(std::move(service)); |
171 return std::move(client); | 222 return std::move(client); |
172 } | 223 } |
173 | 224 |
174 ProfileSyncServiceFactory::SyncClientFactory sync_client_factory_; | 225 ProfileSyncServiceFactory::SyncClientFactory sync_client_factory_; |
175 std::vector<std::unique_ptr<TestModelTypeService>> services_; | 226 std::vector<std::unique_ptr<TestModelTypeService>> services_; |
176 std::vector<TestSyncClient*> clients_; | 227 std::vector<TestSyncClient*> clients_; |
177 bool first_client_ignored_ = false; | 228 bool first_client_ignored_ = false; |
178 | 229 |
| 230 private: |
179 DISALLOW_COPY_AND_ASSIGN(TwoClientUssSyncTest); | 231 DISALLOW_COPY_AND_ASSIGN(TwoClientUssSyncTest); |
180 }; | 232 }; |
181 | 233 |
182 IN_PROC_BROWSER_TEST_F(TwoClientUssSyncTest, Sanity) { | 234 IN_PROC_BROWSER_TEST_F(TwoClientUssSyncTest, Sanity) { |
183 ASSERT_TRUE(SetupSync()); | 235 ASSERT_TRUE(SetupSync()); |
184 ASSERT_EQ(2U, clients_.size()); | 236 ASSERT_EQ(2U, clients_.size()); |
185 ASSERT_EQ(2U, services_.size()); | 237 ASSERT_EQ(2U, services_.size()); |
186 TestModelTypeService* model1 = GetModelTypeService(0); | 238 TestModelTypeService* model1 = GetModelTypeService(0); |
187 TestModelTypeService* model2 = GetModelTypeService(1); | 239 TestModelTypeService* model2 = GetModelTypeService(1); |
188 | 240 |
189 model1->WriteItem("foo", "bar"); | 241 // Add an entity. |
190 ASSERT_TRUE(KeyPresentChecker(model2, "foo").Wait()); | 242 model1->WriteItem(kKey1, kValue1); |
191 EXPECT_EQ("bar", model2->db().GetValue("foo")); | 243 ASSERT_TRUE(DataChecker(model2, kKey1, kValue1).Wait()); |
192 | 244 |
193 model1->DeleteItem("foo"); | 245 // Update an entity. |
194 ASSERT_TRUE(KeyAbsentChecker(model2, "foo").Wait()); | 246 model1->WriteItem(kKey1, kValue2); |
| 247 ASSERT_TRUE(DataChecker(model2, kKey1, kValue2).Wait()); |
| 248 |
| 249 // Delete an entity. |
| 250 model1->DeleteItem(kKey1); |
| 251 ASSERT_TRUE(DataAbsentChecker(model2, kKey1).Wait()); |
195 } | 252 } |
| 253 |
| 254 IN_PROC_BROWSER_TEST_F(TwoClientUssSyncTest, DisableEnable) { |
| 255 ASSERT_TRUE(SetupSync()); |
| 256 TestModelTypeService* model1 = GetModelTypeService(0); |
| 257 TestModelTypeService* model2 = GetModelTypeService(1); |
| 258 |
| 259 // Add an entity to test with. |
| 260 model1->WriteItem(kKey1, kValue1); |
| 261 ASSERT_TRUE(DataChecker(model2, kKey1, kValue1).Wait()); |
| 262 ASSERT_EQ(1U, model1->db().data_count()); |
| 263 ASSERT_EQ(1U, model1->db().metadata_count()); |
| 264 ASSERT_EQ(1U, model2->db().data_count()); |
| 265 ASSERT_EQ(1U, model2->db().metadata_count()); |
| 266 |
| 267 // Disable PREFERENCES. |
| 268 syncer::ModelTypeSet types = syncer::UserSelectableTypes(); |
| 269 types.Remove(syncer::PREFERENCES); |
| 270 GetSyncService(0)->OnUserChoseDatatypes(false, types); |
| 271 |
| 272 // Wait for it to take effect and remove the metadata. |
| 273 ASSERT_TRUE(MetadataAbsentChecker(model1, kKey1).Wait()); |
| 274 ASSERT_EQ(1U, model1->db().data_count()); |
| 275 ASSERT_EQ(0U, model1->db().metadata_count()); |
| 276 // Model 2 should not be affected. |
| 277 ASSERT_EQ(1U, model2->db().data_count()); |
| 278 ASSERT_EQ(1U, model2->db().metadata_count()); |
| 279 |
| 280 // Re-enable PREFERENCES. |
| 281 GetSyncService(0)->OnUserChoseDatatypes(true, syncer::UserSelectableTypes()); |
| 282 |
| 283 // Wait for metadata to be re-added. |
| 284 ASSERT_TRUE(MetadataPresentChecker(model1, kKey1).Wait()); |
| 285 ASSERT_EQ(1U, model1->db().data_count()); |
| 286 ASSERT_EQ(1U, model1->db().metadata_count()); |
| 287 ASSERT_EQ(1U, model2->db().data_count()); |
| 288 ASSERT_EQ(1U, model2->db().metadata_count()); |
| 289 } |
| 290 |
| 291 IN_PROC_BROWSER_TEST_F(TwoClientUssSyncTest, ConflictResolution) { |
| 292 ASSERT_TRUE(SetupSync()); |
| 293 TestModelTypeService* model1 = GetModelTypeService(0); |
| 294 TestModelTypeService* model2 = GetModelTypeService(1); |
| 295 |
| 296 // Write conflicting entities. |
| 297 model1->WriteItem(kKey1, kValue1); |
| 298 model2->WriteItem(kKey1, kValue2); |
| 299 |
| 300 // Wait for them to be resolved to kResolutionValue by the custom conflict |
| 301 // resolution logic in TestModelTypeService. |
| 302 ASSERT_TRUE(DataChecker(model1, kKey1, kResolutionValue).Wait()); |
| 303 ASSERT_TRUE(DataChecker(model2, kKey1, kResolutionValue).Wait()); |
| 304 } |
OLD | NEW |