Chromium Code Reviews| 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/single_client_status_change_check er.h" | 11 #include "chrome/browser/sync/test/integration/single_client_status_change_check er.h" |
| 12 #include "chrome/browser/sync/test/integration/status_change_checker.h" | 12 #include "chrome/browser/sync/test/integration/status_change_checker.h" |
| 13 #include "chrome/browser/sync/test/integration/sync_integration_test_util.h" | 13 #include "chrome/browser/sync/test/integration/sync_integration_test_util.h" |
| 14 #include "chrome/browser/sync/test/integration/sync_test.h" | 14 #include "chrome/browser/sync/test/integration/sync_test.h" |
| 15 #include "components/browser_sync/profile_sync_components_factory_impl.h" | 15 #include "components/browser_sync/profile_sync_components_factory_impl.h" |
| 16 #include "components/browser_sync/profile_sync_service.h" | 16 #include "components/browser_sync/profile_sync_service.h" |
| 17 #include "components/sync/api/fake_model_type_service.h" | 17 #include "components/sync/api/fake_model_type_service.h" |
| 18 | 18 |
| 19 using browser_sync::ChromeSyncClient; | 19 using browser_sync::ChromeSyncClient; |
| 20 using browser_sync::ProfileSyncComponentsFactoryImpl; | 20 using browser_sync::ProfileSyncComponentsFactoryImpl; |
| 21 using syncer::ConflictResolution; | 21 using syncer::ConflictResolution; |
| 22 using syncer::FakeModelTypeService; | 22 using syncer::FakeModelTypeService; |
| 23 using syncer::ModelTypeService; | 23 using syncer::ModelTypeService; |
| 24 using syncer::SharedModelTypeProcessor; | 24 using syncer::SharedModelTypeProcessor; |
| 25 | 25 |
| 26 const char kKey1[] = "key1"; | 26 const char kKey1[] = "key1"; |
| 27 const char kKey2[] = "key2"; | 27 const char kKey2[] = "key2"; |
| 28 const char kKey3[] = "key3"; | |
| 29 const char kKey4[] = "key4"; | |
| 28 const char kValue1[] = "value1"; | 30 const char kValue1[] = "value1"; |
| 29 const char kValue2[] = "value2"; | 31 const char kValue2[] = "value2"; |
| 30 const char kValue3[] = "value3"; | 32 const char kValue3[] = "value3"; |
| 33 const char* kPassphrase = "12345"; | |
|
maxbogue
2016/10/11 15:56:38
That's the stupidest combination I've ever heard i
skym
2016/10/11 16:41:00
:)
| |
| 31 | 34 |
| 32 // A ChromeSyncClient that provides a ModelTypeService for PREFERENCES. | 35 // A ChromeSyncClient that provides a ModelTypeService for PREFERENCES. |
| 33 class TestSyncClient : public ChromeSyncClient { | 36 class TestSyncClient : public ChromeSyncClient { |
| 34 public: | 37 public: |
| 35 TestSyncClient(Profile* profile, ModelTypeService* service) | 38 TestSyncClient(Profile* profile, ModelTypeService* service) |
| 36 : ChromeSyncClient(profile), service_(service) {} | 39 : ChromeSyncClient(profile), service_(service) {} |
| 37 | 40 |
| 38 base::WeakPtr<ModelTypeService> GetModelTypeServiceForType( | 41 base::WeakPtr<ModelTypeService> GetModelTypeServiceForType( |
| 39 syncer::ModelType type) override { | 42 syncer::ModelType type) override { |
| 40 return type == syncer::PREFERENCES | 43 return type == syncer::PREFERENCES |
| (...skipping 186 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 227 bool first_client_ignored_ = false; | 230 bool first_client_ignored_ = false; |
| 228 | 231 |
| 229 private: | 232 private: |
| 230 DISALLOW_COPY_AND_ASSIGN(TwoClientUssSyncTest); | 233 DISALLOW_COPY_AND_ASSIGN(TwoClientUssSyncTest); |
| 231 }; | 234 }; |
| 232 | 235 |
| 233 IN_PROC_BROWSER_TEST_F(TwoClientUssSyncTest, Sanity) { | 236 IN_PROC_BROWSER_TEST_F(TwoClientUssSyncTest, Sanity) { |
| 234 ASSERT_TRUE(SetupSync()); | 237 ASSERT_TRUE(SetupSync()); |
| 235 ASSERT_EQ(2U, clients_.size()); | 238 ASSERT_EQ(2U, clients_.size()); |
| 236 ASSERT_EQ(2U, services_.size()); | 239 ASSERT_EQ(2U, services_.size()); |
| 237 TestModelTypeService* model1 = GetModelTypeService(0); | 240 TestModelTypeService* model0 = GetModelTypeService(0); |
| 238 TestModelTypeService* model2 = GetModelTypeService(1); | 241 TestModelTypeService* model1 = GetModelTypeService(1); |
| 239 | 242 |
| 240 // Add an entity. | 243 // Add an entity. |
| 241 model1->WriteItem(kKey1, kValue1); | 244 model0->WriteItem(kKey1, kValue1); |
| 242 ASSERT_TRUE(DataChecker(model2, kKey1, kValue1).Wait()); | 245 ASSERT_TRUE(DataChecker(model1, kKey1, kValue1).Wait()); |
| 243 | 246 |
| 244 // Update an entity. | 247 // Update an entity. |
| 245 model1->WriteItem(kKey1, kValue2); | 248 model0->WriteItem(kKey1, kValue2); |
| 246 ASSERT_TRUE(DataChecker(model2, kKey1, kValue2).Wait()); | 249 ASSERT_TRUE(DataChecker(model1, kKey1, kValue2).Wait()); |
| 247 | 250 |
| 248 // Delete an entity. | 251 // Delete an entity. |
| 249 model1->DeleteItem(kKey1); | 252 model0->DeleteItem(kKey1); |
| 250 ASSERT_TRUE(DataAbsentChecker(model2, kKey1).Wait()); | 253 ASSERT_TRUE(DataAbsentChecker(model1, kKey1).Wait()); |
| 251 } | 254 } |
| 252 | 255 |
| 253 IN_PROC_BROWSER_TEST_F(TwoClientUssSyncTest, DisableEnable) { | 256 IN_PROC_BROWSER_TEST_F(TwoClientUssSyncTest, DisableEnable) { |
| 254 ASSERT_TRUE(SetupSync()); | 257 ASSERT_TRUE(SetupSync()); |
| 255 TestModelTypeService* model1 = GetModelTypeService(0); | 258 TestModelTypeService* model0 = GetModelTypeService(0); |
| 256 TestModelTypeService* model2 = GetModelTypeService(1); | 259 TestModelTypeService* model1 = GetModelTypeService(1); |
| 257 | 260 |
| 258 // Add an entity to test with. | 261 // Add an entity to test with. |
| 259 model1->WriteItem(kKey1, kValue1); | 262 model0->WriteItem(kKey1, kValue1); |
| 260 ASSERT_TRUE(DataChecker(model2, kKey1, kValue1).Wait()); | 263 ASSERT_TRUE(DataChecker(model1, kKey1, kValue1).Wait()); |
| 264 ASSERT_EQ(1U, model0->db().data_count()); | |
| 265 ASSERT_EQ(1U, model0->db().metadata_count()); | |
| 261 ASSERT_EQ(1U, model1->db().data_count()); | 266 ASSERT_EQ(1U, model1->db().data_count()); |
| 262 ASSERT_EQ(1U, model1->db().metadata_count()); | 267 ASSERT_EQ(1U, model1->db().metadata_count()); |
| 263 ASSERT_EQ(1U, model2->db().data_count()); | |
| 264 ASSERT_EQ(1U, model2->db().metadata_count()); | |
| 265 | 268 |
| 266 // Disable PREFERENCES. | 269 // Disable PREFERENCES. |
| 267 syncer::ModelTypeSet types = syncer::UserSelectableTypes(); | 270 syncer::ModelTypeSet types = syncer::UserSelectableTypes(); |
| 268 types.Remove(syncer::PREFERENCES); | 271 types.Remove(syncer::PREFERENCES); |
| 269 GetSyncService(0)->OnUserChoseDatatypes(false, types); | 272 GetSyncService(0)->OnUserChoseDatatypes(false, types); |
| 270 | 273 |
| 271 // Wait for it to take effect and remove the metadata. | 274 // Wait for it to take effect and remove the metadata. |
| 272 ASSERT_TRUE(MetadataAbsentChecker(model1, kKey1).Wait()); | 275 ASSERT_TRUE(MetadataAbsentChecker(model0, kKey1).Wait()); |
| 276 ASSERT_EQ(1U, model0->db().data_count()); | |
| 277 ASSERT_EQ(0U, model0->db().metadata_count()); | |
| 278 // Model 2 should not be affected. | |
| 273 ASSERT_EQ(1U, model1->db().data_count()); | 279 ASSERT_EQ(1U, model1->db().data_count()); |
| 274 ASSERT_EQ(0U, model1->db().metadata_count()); | 280 ASSERT_EQ(1U, model1->db().metadata_count()); |
| 275 // Model 2 should not be affected. | |
| 276 ASSERT_EQ(1U, model2->db().data_count()); | |
| 277 ASSERT_EQ(1U, model2->db().metadata_count()); | |
| 278 | 281 |
| 279 // Re-enable PREFERENCES. | 282 // Re-enable PREFERENCES. |
| 280 GetSyncService(0)->OnUserChoseDatatypes(true, syncer::UserSelectableTypes()); | 283 GetSyncService(0)->OnUserChoseDatatypes(true, syncer::UserSelectableTypes()); |
| 281 | 284 |
| 282 // Wait for metadata to be re-added. | 285 // Wait for metadata to be re-added. |
| 283 ASSERT_TRUE(MetadataPresentChecker(model1, kKey1).Wait()); | 286 ASSERT_TRUE(MetadataPresentChecker(model0, kKey1).Wait()); |
| 287 ASSERT_EQ(1U, model0->db().data_count()); | |
| 288 ASSERT_EQ(1U, model0->db().metadata_count()); | |
| 284 ASSERT_EQ(1U, model1->db().data_count()); | 289 ASSERT_EQ(1U, model1->db().data_count()); |
| 285 ASSERT_EQ(1U, model1->db().metadata_count()); | 290 ASSERT_EQ(1U, model1->db().metadata_count()); |
| 286 ASSERT_EQ(1U, model2->db().data_count()); | |
| 287 ASSERT_EQ(1U, model2->db().metadata_count()); | |
| 288 } | 291 } |
| 289 | 292 |
| 290 IN_PROC_BROWSER_TEST_F(TwoClientUssSyncTest, ConflictResolution) { | 293 IN_PROC_BROWSER_TEST_F(TwoClientUssSyncTest, ConflictResolution) { |
| 291 ASSERT_TRUE(SetupSync()); | 294 ASSERT_TRUE(SetupSync()); |
| 292 TestModelTypeService* model1 = GetModelTypeService(0); | 295 TestModelTypeService* model0 = GetModelTypeService(0); |
| 293 TestModelTypeService* model2 = GetModelTypeService(1); | 296 TestModelTypeService* model1 = GetModelTypeService(1); |
| 297 model0->SetConflictResolution(ConflictResolution::UseNew( | |
| 298 FakeModelTypeService::GenerateEntityData(kKey1, kValue3))); | |
| 294 model1->SetConflictResolution(ConflictResolution::UseNew( | 299 model1->SetConflictResolution(ConflictResolution::UseNew( |
| 295 FakeModelTypeService::GenerateEntityData(kKey1, kValue3))); | 300 FakeModelTypeService::GenerateEntityData(kKey1, kValue3))); |
| 296 model2->SetConflictResolution(ConflictResolution::UseNew( | |
| 297 FakeModelTypeService::GenerateEntityData(kKey1, kValue3))); | |
| 298 | 301 |
| 299 // Write conflicting entities. | 302 // Write conflicting entities. |
| 300 model1->WriteItem(kKey1, kValue1); | 303 model0->WriteItem(kKey1, kValue1); |
| 301 model2->WriteItem(kKey1, kValue2); | 304 model1->WriteItem(kKey1, kValue2); |
| 302 | 305 |
| 303 // Wait for them to be resolved to kResolutionValue by the custom conflict | 306 // Wait for them to be resolved to kResolutionValue by the custom conflict |
| 304 // resolution logic in TestModelTypeService. | 307 // resolution logic in TestModelTypeService. |
| 308 ASSERT_TRUE(DataChecker(model0, kKey1, kValue3).Wait()); | |
| 305 ASSERT_TRUE(DataChecker(model1, kKey1, kValue3).Wait()); | 309 ASSERT_TRUE(DataChecker(model1, kKey1, kValue3).Wait()); |
| 306 ASSERT_TRUE(DataChecker(model2, kKey1, kValue3).Wait()); | |
| 307 } | 310 } |
| 308 | 311 |
| 309 IN_PROC_BROWSER_TEST_F(TwoClientUssSyncTest, Error) { | 312 IN_PROC_BROWSER_TEST_F(TwoClientUssSyncTest, Error) { |
| 310 ASSERT_TRUE(SetupSync()); | 313 ASSERT_TRUE(SetupSync()); |
| 311 TestModelTypeService* model1 = GetModelTypeService(0); | 314 TestModelTypeService* model0 = GetModelTypeService(0); |
| 312 TestModelTypeService* model2 = GetModelTypeService(1); | 315 TestModelTypeService* model1 = GetModelTypeService(1); |
| 313 | 316 |
| 314 // Add an entity. | 317 // Add an entity. |
| 315 model1->WriteItem(kKey1, kValue1); | 318 model0->WriteItem(kKey1, kValue1); |
| 316 ASSERT_TRUE(DataChecker(model2, kKey1, kValue1).Wait()); | 319 ASSERT_TRUE(DataChecker(model1, kKey1, kValue1).Wait()); |
| 317 | 320 |
| 318 // Set an error in model 2 to trigger in the next GetUpdates. | 321 // Set an error in model 1 to trigger in the next GetUpdates. |
| 319 model2->SetServiceError(syncer::SyncError::DATATYPE_ERROR); | 322 model1->SetServiceError(syncer::SyncError::DATATYPE_ERROR); |
| 320 // Write an item on model 1 to trigger a GetUpdates in model 2. | 323 // Write an item on model 0 to trigger a GetUpdates in model 2. |
| 321 model1->WriteItem(kKey1, kValue2); | 324 model0->WriteItem(kKey1, kValue2); |
| 322 | 325 |
| 323 // The type should stop syncing but keep tracking metadata. | 326 // The type should stop syncing but keep tracking metadata. |
| 324 ASSERT_TRUE(PrefsNotRunningChecker(GetSyncService(1)).Wait()); | 327 ASSERT_TRUE(PrefsNotRunningChecker(GetSyncService(1)).Wait()); |
| 325 ASSERT_EQ(1U, model2->db().metadata_count()); | 328 ASSERT_EQ(1U, model1->db().metadata_count()); |
| 326 model2->WriteItem(kKey2, kValue2); | 329 model1->WriteItem(kKey2, kValue2); |
| 327 ASSERT_EQ(2U, model2->db().metadata_count()); | 330 ASSERT_EQ(2U, model1->db().metadata_count()); |
| 328 } | 331 } |
| 332 | |
| 333 IN_PROC_BROWSER_TEST_F(TwoClientUssSyncTest, Encryption) { | |
| 334 ASSERT_TRUE(SetupSync()); | |
| 335 TestModelTypeService* model0 = GetModelTypeService(0); | |
| 336 TestModelTypeService* model1 = GetModelTypeService(1); | |
| 337 | |
| 338 model0->WriteItem(kKey1, kValue1); | |
| 339 ASSERT_TRUE(DataChecker(model1, kKey1, kValue1).Wait()); | |
| 340 | |
| 341 GetSyncService(0)->SetEncryptionPassphrase(kPassphrase, | |
| 342 syncer::SyncService::EXPLICIT); | |
| 343 ASSERT_TRUE(PassphraseAcceptedChecker(GetSyncService(0)).Wait()); | |
|
maxbogue
2016/10/11 15:56:38
The passphrase can be not accepted?
skym
2016/10/11 16:41:00
If it's async, it can before accepted, and after a
| |
| 344 // Wait for client 1 to know that a passphrase is happening to avoid potential | |
| 345 // race conditions and make the functionality this case tests more consistent. | |
| 346 ASSERT_TRUE(PassphraseRequiredChecker(GetSyncService(1)).Wait()); | |
| 347 | |
| 348 model0->WriteItem(kKey1, kValue2); | |
| 349 model0->WriteItem(kKey2, kValue1); | |
| 350 model1->WriteItem(kKey3, kValue1); | |
| 351 | |
| 352 ASSERT_TRUE(GetSyncService(1)->SetDecryptionPassphrase(kPassphrase)); | |
| 353 ASSERT_TRUE(PassphraseAcceptedChecker(GetSyncService(1)).Wait()); | |
| 354 | |
| 355 model0->WriteItem(kKey4, kValue1); | |
| 356 | |
| 357 ASSERT_TRUE(DataChecker(model1, kKey1, kValue2).Wait()); | |
| 358 ASSERT_TRUE(DataChecker(model1, kKey3, kValue1).Wait()); | |
| 359 ASSERT_TRUE(DataChecker(model1, kKey4, kValue1).Wait()); | |
| 360 | |
| 361 ASSERT_TRUE(DataChecker(model0, kKey1, kValue2).Wait()); | |
|
maxbogue
2016/10/11 15:56:39
Why do you check kKey1 and kKey3 twice but never k
skym
2016/10/11 16:41:00
Whoops, model1 should have checked key2, not key3
| |
| 362 ASSERT_TRUE(DataChecker(model0, kKey3, kValue1).Wait()); | |
| 363 } | |
| 364 | |
| 365 // TODO(skym): Rework nigori updates upon initial load so that this case no | |
| 366 // longer tests anything interesting. Altenatively, if this test case is going | |
| 367 // to stick around long term, we may want to rework this test case to be less | |
| 368 // racy. We could potentially accomplish this by creating or re-creating client | |
| 369 // 1 after we know the encrypted value of kKey1 was written to the server. | |
| 370 IN_PROC_BROWSER_TEST_F(TwoClientUssSyncTest, EncryptionInitialSketchiness) { | |
| 371 ASSERT_TRUE(SetupSync()); | |
| 372 TestModelTypeService* model0 = GetModelTypeService(0); | |
| 373 TestModelTypeService* model1 = GetModelTypeService(1); | |
| 374 | |
| 375 GetSyncService(0)->SetEncryptionPassphrase(kPassphrase, | |
| 376 syncer::SyncService::EXPLICIT); | |
| 377 ASSERT_TRUE(PassphraseAcceptedChecker(GetSyncService(0)).Wait()); | |
| 378 | |
| 379 // Right after client 0 initializes, write an item with the new passphrase. | |
| 380 // Unfourtunately, the behavior here is kind of undefind and we're relying on | |
|
maxbogue
2016/10/11 15:56:38
"Unfortunately", "undefined"
skym
2016/10/11 16:41:00
Done.
| |
| 381 // race conditoins to hit the logic we're trying to test. What typically | |
|
maxbogue
2016/10/11 15:56:39
"conditions"
Can you make it clearer which things
skym
2016/10/11 16:41:00
Done. And I believe so, although it consistently e
| |
| 382 // happens is that client 1 is going to perform their initial download, and is | |
| 383 // going to restore/migrate nigori to its initial/default value. It will also | |
|
maxbogue
2016/10/11 15:56:38
So the client 1 nigori is going from what to what?
skym
2016/10/11 16:41:00
I'm not sure actually. I was just printing out key
| |
| 384 // be in this first GetUpdates that it retrieves the encrypted preference | |
| 385 // entity. It can correctly use the default nigori encryption, and picks up | |
|
maxbogue
2016/10/11 15:56:38
Why can it use default encryption if it should be
skym
2016/10/11 16:41:00
If it's just temporary, hasn't really mattered bef
| |
| 386 // that preferences needs to be encrypted from the passphrase setting by | |
| 387 // client 0. But at this time the worker doesn't have the real passphrase | |
| 388 // nigori, and bizarrely it will never get it during this GetUpdates cycle. It | |
|
maxbogue
2016/10/11 15:56:38
Seems like something that's broken...
skym
2016/10/11 16:41:00
It does seem odd.
| |
| 389 // isn't until a further GetUpdates call that the passphrase encryption key | |
| 390 // and cryptographer reaches the worker. This is particularly difficult for | |
| 391 // the worker to handle, because it cannot be certain it has the latest | |
| 392 // encryption key from looking at its cryptographer. Yes, this case should be | |
| 393 // a unit test, and it is, see ModelTypeWorkerTest.MultipleEncryptionKeys, but | |
| 394 // this test shows that this is a case that we currently need to handle. | |
| 395 model0->WriteItem(kKey1, kValue1); | |
| 396 | |
| 397 ASSERT_TRUE(PassphraseRequiredChecker(GetSyncService(1)).Wait()); | |
| 398 ASSERT_TRUE(GetSyncService(1)->SetDecryptionPassphrase(kPassphrase)); | |
| 399 ASSERT_TRUE(PassphraseAcceptedChecker(GetSyncService(1)).Wait()); | |
| 400 | |
| 401 ASSERT_TRUE(DataChecker(model1, kKey1, kValue1).Wait()); | |
| 402 } | |
| OLD | NEW |