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

Side by Side Diff: chrome/browser/sync/test/integration/two_client_uss_sync_test.cc

Issue 2401083003: [Sync] Adding integration tests for USS encryption and fixing a worker bug. (Closed)
Patch Set: Removing "Encryptoin keys" capitalization fix. Created 4 years, 2 months 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
OLDNEW
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
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 }
OLDNEW
« no previous file with comments | « no previous file | components/sync/engine_impl/model_type_worker.h » ('j') | components/sync/engine_impl/model_type_worker.h » ('J')

Powered by Google App Engine
This is Rietveld 408576698