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

Side by Side Diff: chrome/browser/sync/profile_sync_service_harness.cc

Issue 7655055: [Sync] Make BackendMigrator not wait for full sync cycles (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Cleanup Created 9 years, 3 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 | 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 "chrome/browser/sync/profile_sync_service_harness.h" 5 #include "chrome/browser/sync/profile_sync_service_harness.h"
6 6
7 #include <stddef.h> 7 #include <stddef.h>
8 #include <algorithm> 8 #include <algorithm>
9 #include <iterator> 9 #include <iterator>
10 #include <ostream> 10 #include <ostream>
11 #include <set> 11 #include <set>
12 #include <sstream> 12 #include <sstream>
13 #include <vector> 13 #include <vector>
14 14
15 #include "base/base64.h"
15 #include "base/json/json_writer.h" 16 #include "base/json/json_writer.h"
16 #include "base/logging.h" 17 #include "base/logging.h"
17 #include "base/memory/ref_counted.h" 18 #include "base/memory/ref_counted.h"
18 #include "base/message_loop.h" 19 #include "base/message_loop.h"
19 #include "base/task.h" 20 #include "base/task.h"
20 #include "base/tracked.h" 21 #include "base/tracked.h"
21 #include "chrome/browser/profiles/profile.h" 22 #include "chrome/browser/profiles/profile.h"
22 #include "chrome/browser/sync/sessions/session_state.h" 23 #include "chrome/browser/sync/sessions/session_state.h"
23 #include "chrome/browser/sync/signin_manager.h" 24 #include "chrome/browser/sync/signin_manager.h"
24 #include "chrome/browser/sync/sync_ui_util.h" 25 #include "chrome/browser/sync/sync_ui_util.h"
(...skipping 188 matching lines...) Expand 10 before | Expand all | Expand 10 after
213 void ProfileSyncServiceHarness::SignalStateCompleteWithNextState( 214 void ProfileSyncServiceHarness::SignalStateCompleteWithNextState(
214 WaitState next_state) { 215 WaitState next_state) {
215 wait_state_ = next_state; 216 wait_state_ = next_state;
216 SignalStateComplete(); 217 SignalStateComplete();
217 } 218 }
218 219
219 void ProfileSyncServiceHarness::SignalStateComplete() { 220 void ProfileSyncServiceHarness::SignalStateComplete() {
220 MessageLoop::current()->Quit(); 221 MessageLoop::current()->Quit();
221 } 222 }
222 223
224 void ProfileSyncServiceHarness::UpdateMigrationState() {
225 if (service()->HasPendingBackendMigration()) {
226 // Merge current pending migration types into
227 // |pending_migration_types_|.
Raghu Simha 2011/09/01 03:53:06 Should we not simply replace pending_migration_typ
akalin 2011/09/01 04:03:24 The idea is to accumulate all migrated types inste
Raghu Simha 2011/09/01 04:23:58 SGTM.
228 syncable::ModelTypeSet new_pending_migration_types =
229 service()->GetPendingMigrationTypesForTest();
230 syncable::ModelTypeSet temp;
231 std::set_union(pending_migration_types_.begin(),
232 pending_migration_types_.end(),
233 new_pending_migration_types.begin(),
234 new_pending_migration_types.end(),
235 std::inserter(temp, temp.end()));
236 std::swap(pending_migration_types_, temp);
237 VLOG(1) << profile_debug_name_ << ": new pending migration types "
238 << syncable::ModelTypeSetToString(pending_migration_types_);
239 } else {
240 // Merge just-finished pending migration types into
241 // |migration_types_|.
242 syncable::ModelTypeSet temp;
243 std::set_union(pending_migration_types_.begin(),
244 pending_migration_types_.end(),
245 migrated_types_.begin(),
246 migrated_types_.end(),
247 std::inserter(temp, temp.end()));
248 std::swap(migrated_types_, temp);
249 pending_migration_types_.clear();
250 VLOG(1) << profile_debug_name_ << ": new migrated types "
251 << syncable::ModelTypeSetToString(migrated_types_);
252 }
253 }
254
223 bool ProfileSyncServiceHarness::RunStateChangeMachine() { 255 bool ProfileSyncServiceHarness::RunStateChangeMachine() {
224 WaitState original_wait_state = wait_state_; 256 WaitState original_wait_state = wait_state_;
225 switch (wait_state_) { 257 switch (wait_state_) {
226 case WAITING_FOR_ON_BACKEND_INITIALIZED: { 258 case WAITING_FOR_ON_BACKEND_INITIALIZED: {
227 VLOG(1) << GetClientInfoString("WAITING_FOR_ON_BACKEND_INITIALIZED"); 259 VLOG(1) << GetClientInfoString("WAITING_FOR_ON_BACKEND_INITIALIZED");
228 if (service()->sync_initialized()) { 260 if (service()->sync_initialized()) {
229 // The sync backend is initialized. 261 // The sync backend is initialized.
230 SignalStateCompleteWithNextState(WAITING_FOR_INITIAL_SYNC); 262 SignalStateCompleteWithNextState(WAITING_FOR_INITIAL_SYNC);
231 } 263 }
232 break; 264 break;
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after
337 VLOG(1) << GetClientInfoString( 369 VLOG(1) << GetClientInfoString(
338 "WAITING_FOR_EXPONENTIAL_BACKOFF_VERIFICATION"); 370 "WAITING_FOR_EXPONENTIAL_BACKOFF_VERIFICATION");
339 const browser_sync::sessions::SyncSessionSnapshot *snap = 371 const browser_sync::sessions::SyncSessionSnapshot *snap =
340 GetLastSessionSnapshot(); 372 GetLastSessionSnapshot();
341 CHECK(snap); 373 CHECK(snap);
342 retry_verifier_.VerifyRetryInterval(*snap); 374 retry_verifier_.VerifyRetryInterval(*snap);
343 if (retry_verifier_.done()) 375 if (retry_verifier_.done())
344 SignalStateCompleteWithNextState(WAITING_FOR_NOTHING); 376 SignalStateCompleteWithNextState(WAITING_FOR_NOTHING);
345 break; 377 break;
346 } 378 }
379 case WAITING_FOR_MIGRATION_TO_START: {
380 VLOG(1) << GetClientInfoString("WAITING_FOR_MIGRATION_TO_START");
381 if (service()->HasPendingBackendMigration()) {
382 SignalStateCompleteWithNextState(WAITING_FOR_MIGRATION_TO_FINISH);
383 }
384 break;
385 }
386 case WAITING_FOR_MIGRATION_TO_FINISH: {
387 VLOG(1) << GetClientInfoString("WAITING_FOR_MIGRATION_TO_FINISH");
388 if (!service()->HasPendingBackendMigration()) {
389 SignalStateCompleteWithNextState(WAITING_FOR_NOTHING);
390 }
391 break;
392 }
347 case SERVER_UNREACHABLE: { 393 case SERVER_UNREACHABLE: {
348 VLOG(1) << GetClientInfoString("SERVER_UNREACHABLE"); 394 VLOG(1) << GetClientInfoString("SERVER_UNREACHABLE");
349 if (GetStatus().server_reachable) { 395 if (GetStatus().server_reachable) {
350 // The client was offline due to the network being disabled, but is now 396 // The client was offline due to the network being disabled, but is now
351 // back online. Wait for the pending sync cycle to complete. 397 // back online. Wait for the pending sync cycle to complete.
352 SignalStateCompleteWithNextState(WAITING_FOR_SYNC_TO_FINISH); 398 SignalStateCompleteWithNextState(WAITING_FOR_SYNC_TO_FINISH);
353 } 399 }
354 break; 400 break;
355 } 401 }
356 case SET_PASSPHRASE_FAILED: { 402 case SET_PASSPHRASE_FAILED: {
(...skipping 20 matching lines...) Expand all
377 } 423 }
378 default: 424 default:
379 // Invalid state during observer callback which may be triggered by other 425 // Invalid state during observer callback which may be triggered by other
380 // classes using the the UI message loop. Defer to their handling. 426 // classes using the the UI message loop. Defer to their handling.
381 break; 427 break;
382 } 428 }
383 return original_wait_state != wait_state_; 429 return original_wait_state != wait_state_;
384 } 430 }
385 431
386 void ProfileSyncServiceHarness::OnStateChanged() { 432 void ProfileSyncServiceHarness::OnStateChanged() {
433 UpdateMigrationState();
Raghu Simha 2011/09/01 03:53:06 Any particular reason for calling UpdateMigrationS
akalin 2011/09/01 04:03:24 Addressed in latest patch.
387 RunStateChangeMachine(); 434 RunStateChangeMachine();
388 } 435 }
389 436
390 bool ProfileSyncServiceHarness::AwaitPassphraseRequired() { 437 bool ProfileSyncServiceHarness::AwaitPassphraseRequired() {
391 VLOG(1) << GetClientInfoString("AwaitPassphraseRequired"); 438 VLOG(1) << GetClientInfoString("AwaitPassphraseRequired");
392 if (wait_state_ == SYNC_DISABLED) { 439 if (wait_state_ == SYNC_DISABLED) {
393 LOG(ERROR) << "Sync disabled for " << profile_debug_name_ << "."; 440 LOG(ERROR) << "Sync disabled for " << profile_debug_name_ << ".";
394 return false; 441 return false;
395 } 442 }
396 443
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
462 if (wait_state_ == SYNC_DISABLED) { 509 if (wait_state_ == SYNC_DISABLED) {
463 LOG(ERROR) << "Sync disabled for " << profile_debug_name_ << "."; 510 LOG(ERROR) << "Sync disabled for " << profile_debug_name_ << ".";
464 return false; 511 return false;
465 } 512 }
466 513
467 if (IsSynced()) { 514 if (IsSynced()) {
468 // Client is already synced; don't wait. 515 // Client is already synced; don't wait.
469 return true; 516 return true;
470 } 517 }
471 518
472 return AwaitSyncCycleCompletionHelper(reason);
473 }
474
475 bool ProfileSyncServiceHarness::AwaitNextSyncCycleCompletion(
476 const std::string& reason) {
477 VLOG(1) << GetClientInfoString("AwaitNextSyncCycleCompletion");
478 return AwaitSyncCycleCompletionHelper(reason);
479 }
480
481 bool ProfileSyncServiceHarness::AwaitSyncCycleCompletionHelper(
482 const std::string& reason) {
483 if (wait_state_ == SERVER_UNREACHABLE) { 519 if (wait_state_ == SERVER_UNREACHABLE) {
484 // Client was offline; wait for it to go online, and then wait for sync. 520 // Client was offline; wait for it to go online, and then wait for sync.
485 AwaitStatusChangeWithTimeout(kLiveSyncOperationTimeoutMs, reason); 521 AwaitStatusChangeWithTimeout(kLiveSyncOperationTimeoutMs, reason);
486 DCHECK_EQ(wait_state_, WAITING_FOR_SYNC_TO_FINISH); 522 DCHECK_EQ(wait_state_, WAITING_FOR_SYNC_TO_FINISH);
487 return AwaitStatusChangeWithTimeout(kLiveSyncOperationTimeoutMs, reason); 523 return AwaitStatusChangeWithTimeout(kLiveSyncOperationTimeoutMs, reason);
488 } 524 }
489 525
490 DCHECK(service()->sync_initialized()); 526 DCHECK(service()->sync_initialized());
491 wait_state_ = WAITING_FOR_SYNC_TO_FINISH; 527 wait_state_ = WAITING_FOR_SYNC_TO_FINISH;
492 AwaitStatusChangeWithTimeout(kLiveSyncOperationTimeoutMs, reason); 528 AwaitStatusChangeWithTimeout(kLiveSyncOperationTimeoutMs, reason);
(...skipping 22 matching lines...) Expand all
515 const browser_sync::sessions::SyncSessionSnapshot *snap = 551 const browser_sync::sessions::SyncSessionSnapshot *snap =
516 GetLastSessionSnapshot(); 552 GetLastSessionSnapshot();
517 CHECK(snap); 553 CHECK(snap);
518 retry_verifier_.Initialize(*snap); 554 retry_verifier_.Initialize(*snap);
519 wait_state_ = WAITING_FOR_EXPONENTIAL_BACKOFF_VERIFICATION; 555 wait_state_ = WAITING_FOR_EXPONENTIAL_BACKOFF_VERIFICATION;
520 AwaitStatusChangeWithTimeout(kExponentialBackoffVerificationTimeoutMs, 556 AwaitStatusChangeWithTimeout(kExponentialBackoffVerificationTimeoutMs,
521 "Verify Exponential backoff"); 557 "Verify Exponential backoff");
522 return (retry_verifier_.Succeeded()); 558 return (retry_verifier_.Succeeded());
523 } 559 }
524 560
561 bool ProfileSyncServiceHarness::AwaitMigration(
562 const syncable::ModelTypeSet& expected_migrated_types) {
563 VLOG(1) << GetClientInfoString("AwaitMigration");
564 VLOG(1) << profile_debug_name_ << ": waiting until migration is done for "
565 << syncable::ModelTypeSetToString(expected_migrated_types);
566 while (true) {
567 bool migration_finished =
568 std::includes(migrated_types_.begin(), migrated_types_.end(),
569 expected_migrated_types.begin(),
570 expected_migrated_types.end());
571 VLOG(1) << "Migrated types "
572 << syncable::ModelTypeSetToString(migrated_types_)
573 << (migration_finished ? " contains " : " does not contain ")
574 << syncable::ModelTypeSetToString(expected_migrated_types);
575 if (migration_finished) {
576 return true;
577 }
578
579 if (service()->HasPendingBackendMigration()) {
580 wait_state_ = WAITING_FOR_MIGRATION_TO_FINISH;
581 } else {
582 wait_state_ = WAITING_FOR_MIGRATION_TO_START;
583 AwaitStatusChangeWithTimeout(kLiveSyncOperationTimeoutMs,
584 "Wait for migration to start");
585 if (wait_state_ != WAITING_FOR_MIGRATION_TO_FINISH) {
586 VLOG(1) << profile_debug_name_
587 << ": wait state = " << wait_state_
588 << " after migration start is not "
589 << "WAITING_FOR_MIGRATION_TO_FINISH";
590 return false;
591 }
592 }
593 AwaitStatusChangeWithTimeout(kLiveSyncOperationTimeoutMs,
594 "Wait for migration to finish");
595 if (wait_state_ != WAITING_FOR_NOTHING) {
596 VLOG(1) << profile_debug_name_
597 << ": wait state = " << wait_state_
598 << " after migration finish is not WAITING_FOR_NOTHING";
599 return false;
600 }
601 if (!AwaitSyncCycleCompletion(
602 "Config sync cycle after migration cycle")) {
603 return false;
604 }
605 }
606 }
607
525 bool ProfileSyncServiceHarness::AwaitMutualSyncCycleCompletion( 608 bool ProfileSyncServiceHarness::AwaitMutualSyncCycleCompletion(
526 ProfileSyncServiceHarness* partner) { 609 ProfileSyncServiceHarness* partner) {
527 VLOG(1) << GetClientInfoString("AwaitMutualSyncCycleCompletion"); 610 VLOG(1) << GetClientInfoString("AwaitMutualSyncCycleCompletion");
528 if (!AwaitSyncCycleCompletion("Sync cycle completion on active client.")) 611 if (!AwaitSyncCycleCompletion("Sync cycle completion on active client."))
529 return false; 612 return false;
530 return partner->WaitUntilTimestampMatches(this, 613 return partner->WaitUntilTimestampMatches(this,
531 "Sync cycle completion on passive client."); 614 "Sync cycle completion on passive client.");
532 } 615 }
533 616
534 bool ProfileSyncServiceHarness::AwaitGroupSyncCycleCompletion( 617 bool ProfileSyncServiceHarness::AwaitGroupSyncCycleCompletion(
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after
634 !service()->HasPendingBackendMigration() && 717 !service()->HasPendingBackendMigration() &&
635 service()->passphrase_required_reason() != 718 service()->passphrase_required_reason() !=
636 sync_api::REASON_SET_PASSPHRASE_FAILED; 719 sync_api::REASON_SET_PASSPHRASE_FAILED;
637 VLOG(1) << GetClientInfoString( 720 VLOG(1) << GetClientInfoString(
638 is_synced ? "IsSynced: true" : "IsSynced: false"); 721 is_synced ? "IsSynced: true" : "IsSynced: false");
639 return is_synced; 722 return is_synced;
640 } 723 }
641 724
642 bool ProfileSyncServiceHarness::MatchesOtherClient( 725 bool ProfileSyncServiceHarness::MatchesOtherClient(
643 ProfileSyncServiceHarness* partner) { 726 ProfileSyncServiceHarness* partner) {
644 if (!IsSynced()) 727 // TODO(akalin): Shouldn't this with the intersection check?
Raghu Simha 2011/09/01 03:53:06 Is this comment Yoda-speak? :)
akalin 2011/09/01 04:03:24 Fixed!
728 // Otherwise, this function isn't symmetric.
729 if (!IsSynced()) {
730 VLOG(1) << profile_debug_name_ << ": not synced, assuming doesn't match";
Raghu Simha 2011/09/01 03:53:06 This should probably be a VLOG(2), since it's a ge
akalin 2011/09/01 04:03:24 Done.
645 return false; 731 return false;
732 }
646 733
647 // Only look for a match if we have at least one enabled datatype in 734 // Only look for a match if we have at least one enabled datatype in
648 // common with the partner client. 735 // common with the partner client.
649 syncable::ModelTypeSet types, other_types, intersection_types; 736 syncable::ModelTypeSet types, other_types, intersection_types;
650 service()->GetPreferredDataTypes(&types); 737 service()->GetPreferredDataTypes(&types);
651 partner->service()->GetPreferredDataTypes(&other_types); 738 partner->service()->GetPreferredDataTypes(&other_types);
652 std::set_intersection(types.begin(), types.end(), other_types.begin(), 739 std::set_intersection(types.begin(), types.end(), other_types.begin(),
653 other_types.end(), 740 other_types.end(),
654 inserter(intersection_types, 741 inserter(intersection_types,
655 intersection_types.begin())); 742 intersection_types.begin()));
743
744 VLOG(1) << profile_debug_name_ << ", " << partner->profile_debug_name_
745 << ": common types are "
746 << syncable::ModelTypeSetToString(intersection_types);
747
748 if (!intersection_types.empty() && !partner->IsSynced()) {
749 VLOG(1) << "non-empty common types and "
Raghu Simha 2011/09/01 03:53:06 Same as above. This too should probably be a VLOG(
akalin 2011/09/01 04:03:24 Done.
750 << partner->profile_debug_name_ << " isn't synced";
751 return false;
752 }
753
656 for (syncable::ModelTypeSet::iterator i = intersection_types.begin(); 754 for (syncable::ModelTypeSet::iterator i = intersection_types.begin();
657 i != intersection_types.end(); 755 i != intersection_types.end(); ++i) {
658 ++i) { 756 const std::string timestamp = GetUpdatedTimestamp(*i);
659 if (!partner->IsSynced() || 757 const std::string partner_timestamp = partner->GetUpdatedTimestamp(*i);
660 partner->GetUpdatedTimestamp(*i) != GetUpdatedTimestamp(*i)) { 758 if (timestamp != partner_timestamp) {
759 if (VLOG_IS_ON(1)) {
760 std::string timestamp_base64, partner_timestamp_base64;
761 if (!base::Base64Encode(timestamp, &timestamp_base64)) {
762 NOTREACHED();
763 }
764 if (!base::Base64Encode(
765 partner_timestamp, &partner_timestamp_base64)) {
766 NOTREACHED();
767 }
768 VLOG(1) << syncable::ModelTypeToString(*i) << ": "
769 << profile_debug_name_ << " timestamp = "
770 << timestamp_base64 << ", "
771 << partner->profile_debug_name_
772 << " partner timestamp = "
773 << partner_timestamp_base64;
774 }
661 return false; 775 return false;
662 } 776 }
663 } 777 }
664 return true; 778 return true;
665 } 779 }
666 780
667 const SyncSessionSnapshot* 781 const SyncSessionSnapshot*
668 ProfileSyncServiceHarness::GetLastSessionSnapshot() const { 782 ProfileSyncServiceHarness::GetLastSessionSnapshot() const {
669 DCHECK(service_ != NULL) << "Sync service has not yet been set up."; 783 DCHECK(service_ != NULL) << "Sync service has not yet been set up.";
670 if (service_->sync_initialized()) { 784 if (service_->sync_initialized()) {
(...skipping 224 matching lines...) Expand 10 before | Expand all | Expand 10 after
895 return (synced_types.count(type) != 0); 1009 return (synced_types.count(type) != 0);
896 } 1010 }
897 1011
898 std::string ProfileSyncServiceHarness::GetServiceStatus() { 1012 std::string ProfileSyncServiceHarness::GetServiceStatus() {
899 DictionaryValue value; 1013 DictionaryValue value;
900 sync_ui_util::ConstructAboutInformation(service_, &value); 1014 sync_ui_util::ConstructAboutInformation(service_, &value);
901 std::string service_status; 1015 std::string service_status;
902 base::JSONWriter::Write(&value, true, &service_status); 1016 base::JSONWriter::Write(&value, true, &service_status);
903 return service_status; 1017 return service_status;
904 } 1018 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698