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

Unified Diff: chrome/browser/sync/profile_sync_service_harness.cc

Issue 7861013: Fix the false-positive detection of commit errors (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Another attempt at detecting errors Created 9 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « chrome/browser/sync/profile_sync_service_harness.h ('k') | chrome/browser/sync/profile_sync_service_mock.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: chrome/browser/sync/profile_sync_service_harness.cc
diff --git a/chrome/browser/sync/profile_sync_service_harness.cc b/chrome/browser/sync/profile_sync_service_harness.cc
index c25ec5424830f0c3454cb91ff42260064c137976..b1b0dd6b4134d2eb39e2957d184dc31eab5b7248 100644
--- a/chrome/browser/sync/profile_sync_service_harness.cc
+++ b/chrome/browser/sync/profile_sync_service_harness.cc
@@ -256,7 +256,7 @@ bool ProfileSyncServiceHarness::RunStateChangeMachine() {
}
case WAITING_FOR_INITIAL_SYNC: {
VLOG(1) << GetClientInfoString("WAITING_FOR_INITIAL_SYNC");
- if (IsSynced()) {
+ if (IsFullySynced()) {
// The first sync cycle is now complete. We can start running tests.
SignalStateCompleteWithNextState(FULLY_SYNCED);
break;
@@ -270,9 +270,9 @@ bool ProfileSyncServiceHarness::RunStateChangeMachine() {
}
break;
}
- case WAITING_FOR_SYNC_TO_FINISH: {
- VLOG(1) << GetClientInfoString("WAITING_FOR_SYNC_TO_FINISH");
- if (IsSynced()) {
+ case WAITING_FOR_FULL_SYNC: {
+ VLOG(1) << GetClientInfoString("WAITING_FOR_FULL_SYNC");
+ if (IsFullySynced()) {
// The sync cycle we were waiting for is complete.
SignalStateCompleteWithNextState(FULLY_SYNCED);
break;
@@ -292,6 +292,13 @@ bool ProfileSyncServiceHarness::RunStateChangeMachine() {
}
break;
}
+ case WAITING_FOR_DATA_SYNC: {
+ if (IsDataSynced()) {
+ SignalStateCompleteWithNextState(FULLY_SYNCED);
+ break;
+ }
+ break;
+ }
case WAITING_FOR_UPDATES: {
VLOG(1) << GetClientInfoString("WAITING_FOR_UPDATES");
DCHECK(timestamp_match_partner_);
@@ -329,7 +336,7 @@ bool ProfileSyncServiceHarness::RunStateChangeMachine() {
// sub-expressions. See crbug.com/98607, crbug.com/95619.
// TODO(rlarocque): Figure out a less brittle way of detecting this.
if (IsTypeEncrypted(waiting_for_encryption_type_) &&
- IsSynced() &&
+ IsFullySynced() &&
GetLastSessionSnapshot()->num_conflicting_updates == 0) {
// Encryption is now complete for the the type in which we were waiting.
SignalStateCompleteWithNextState(FULLY_SYNCED);
@@ -403,7 +410,7 @@ bool ProfileSyncServiceHarness::RunStateChangeMachine() {
if (GetStatus().server_reachable) {
// The client was offline due to the network being disabled, but is now
// back online. Wait for the pending sync cycle to complete.
- SignalStateCompleteWithNextState(WAITING_FOR_SYNC_TO_FINISH);
+ SignalStateCompleteWithNextState(WAITING_FOR_FULL_SYNC);
}
break;
}
@@ -544,15 +551,38 @@ bool ProfileSyncServiceHarness::AwaitSyncRestart() {
"Waiting for sync configuration.");
}
-bool ProfileSyncServiceHarness::AwaitSyncCycleCompletion(
+bool ProfileSyncServiceHarness::AwaitDataSyncCompletion(
+ const std::string& reason) {
+ VLOG(1) << GetClientInfoString("AwaitDataSyncCompletion");
+
+ DCHECK(service()->sync_initialized());
+ DCHECK_NE(wait_state_, SYNC_DISABLED);
+ DCHECK_NE(wait_state_, SERVER_UNREACHABLE);
+
+ if (IsDataSynced()) {
+ // Client is already synced; don't wait.
+ return true;
+ }
+
+ wait_state_ = WAITING_FOR_DATA_SYNC;
+ AwaitStatusChangeWithTimeout(kLiveSyncOperationTimeoutMs, reason);
+ if (wait_state_ == FULLY_SYNCED) {
+ return true;
+ } else {
+ LOG(ERROR) << "AwaitDataSyncCompletion failed, state is now: " << wait_state_;
+ return false;
+ }
+}
+
+bool ProfileSyncServiceHarness::AwaitFullSyncCompletion(
const std::string& reason) {
- VLOG(1) << GetClientInfoString("AwaitSyncCycleCompletion");
+ VLOG(1) << GetClientInfoString("AwaitFullSyncCompletion");
if (wait_state_ == SYNC_DISABLED) {
LOG(ERROR) << "Sync disabled for " << profile_debug_name_ << ".";
return false;
}
- if (IsSynced()) {
+ if (IsFullySynced()) {
// Client is already synced; don't wait.
return true;
}
@@ -560,12 +590,12 @@ bool ProfileSyncServiceHarness::AwaitSyncCycleCompletion(
if (wait_state_ == SERVER_UNREACHABLE) {
// Client was offline; wait for it to go online, and then wait for sync.
AwaitStatusChangeWithTimeout(kLiveSyncOperationTimeoutMs, reason);
- DCHECK_EQ(wait_state_, WAITING_FOR_SYNC_TO_FINISH);
+ DCHECK_EQ(wait_state_, WAITING_FOR_FULL_SYNC);
return AwaitStatusChangeWithTimeout(kLiveSyncOperationTimeoutMs, reason);
}
DCHECK(service()->sync_initialized());
- wait_state_ = WAITING_FOR_SYNC_TO_FINISH;
+ wait_state_ = WAITING_FOR_FULL_SYNC;
AwaitStatusChangeWithTimeout(kLiveSyncOperationTimeoutMs, reason);
if (wait_state_ == FULLY_SYNCED) {
// Client is online; sync was successful.
@@ -650,7 +680,14 @@ bool ProfileSyncServiceHarness::AwaitMigration(
<< " after migration finish is not WAITING_FOR_NOTHING";
return false;
}
- if (!AwaitSyncCycleCompletion(
+ // We must use AwaitDataSyncCompletion rather than the more common
+ // AwaitFullSyncCompletion. As long as crbug.com/97780 is open, we will
+ // rely on self-notifiations to ensure that timestamps are udpated, which
+ // allows AwaitFullSyncCompletion to return. However, in some migration
+ // tests these notifications are completely disabled, so the timestamps do
+ // not get updated. This is why we must use the less strict condition,
+ // AwaitDataSyncCompletion.
+ if (!AwaitDataSyncCompletion(
"Config sync cycle after migration cycle")) {
return false;
}
@@ -660,7 +697,7 @@ bool ProfileSyncServiceHarness::AwaitMigration(
bool ProfileSyncServiceHarness::AwaitMutualSyncCycleCompletion(
ProfileSyncServiceHarness* partner) {
VLOG(1) << GetClientInfoString("AwaitMutualSyncCycleCompletion");
- if (!AwaitSyncCycleCompletion("Sync cycle completion on active client."))
+ if (!AwaitFullSyncCompletion("Sync cycle completion on active client."))
return false;
return partner->WaitUntilTimestampMatches(this,
"Sync cycle completion on passive client.");
@@ -669,7 +706,7 @@ bool ProfileSyncServiceHarness::AwaitMutualSyncCycleCompletion(
bool ProfileSyncServiceHarness::AwaitGroupSyncCycleCompletion(
std::vector<ProfileSyncServiceHarness*>& partners) {
VLOG(1) << GetClientInfoString("AwaitGroupSyncCycleCompletion");
- if (!AwaitSyncCycleCompletion("Sync cycle completion on active client."))
+ if (!AwaitFullSyncCompletion("Sync cycle completion on active client."))
return false;
bool return_value = true;
for (std::vector<ProfileSyncServiceHarness*>::iterator it =
@@ -751,27 +788,49 @@ ProfileSyncService::Status ProfileSyncServiceHarness::GetStatus() {
return service()->QueryDetailedSyncStatus();
}
-bool ProfileSyncServiceHarness::IsSynced() {
- if (service() == NULL) {
- VLOG(1) << GetClientInfoString("IsSynced: false");
- return false;
- }
- const SyncSessionSnapshot* snap = GetLastSessionSnapshot();
- // TODO(rsimha): Remove additional checks of snap->has_more_to_sync and
- // snap->unsynced_count once http://crbug.com/48989 is fixed.
- bool is_synced = snap &&
+// We use this function to share code between IsFullySynced and IsDataSynced
+// while ensuring that all conditions are evaluated using on the same snapshot.
+bool ProfileSyncServiceHarness::IsDataSyncedImpl(
+ const browser_sync::sessions::SyncSessionSnapshot *snap) {
+ return snap &&
snap->num_blocking_conflicting_updates == 0 &&
ServiceIsPushingChanges() &&
GetStatus().notifications_enabled &&
!service()->HasUnsyncedItems() &&
!snap->has_more_to_sync &&
- snap->unsynced_count == 0 &&
!HasPendingBackendMigration() &&
service()->passphrase_required_reason() !=
- sync_api::REASON_SET_PASSPHRASE_FAILED;
+ sync_api::REASON_SET_PASSPHRASE_FAILED;
+}
+
+bool ProfileSyncServiceHarness::IsDataSynced() {
+ if (service() == NULL) {
+ VLOG(1) << GetClientInfoString("IsDataSynced(): false");
+ return false;
+ }
+
+ const SyncSessionSnapshot* snap = GetLastSessionSnapshot();
+ bool is_data_synced = IsDataSyncedImpl(snap);
+
+ VLOG(1) << GetClientInfoString(
+ is_data_synced ? "IsDataSynced: true" : "IsDataSynced: false");
+ return is_data_synced;
+}
+
+bool ProfileSyncServiceHarness::IsFullySynced() {
+ if (service() == NULL) {
+ VLOG(1) << GetClientInfoString("IsFullySynced: false");
+ return false;
+ }
+ const SyncSessionSnapshot* snap = GetLastSessionSnapshot();
+ // snap->unsynced_count == 0 is a fairly reliable indicator of whether or not
+ // our timestamp is in sync with the server.
+ bool is_fully_synced = IsDataSyncedImpl(snap) &&
+ snap->unsynced_count == 0;
+
VLOG(1) << GetClientInfoString(
- is_synced ? "IsSynced: true" : "IsSynced: false");
- return is_synced;
+ is_fully_synced ? "IsFullySynced: true" : "IsFullySynced: false");
+ return is_fully_synced;
}
bool ProfileSyncServiceHarness::HasPendingBackendMigration() {
@@ -784,7 +843,7 @@ bool ProfileSyncServiceHarness::MatchesOtherClient(
ProfileSyncServiceHarness* partner) {
// TODO(akalin): Shouldn't this belong with the intersection check?
// Otherwise, this function isn't symmetric.
- if (!IsSynced()) {
+ if (!IsFullySynced()) {
VLOG(2) << profile_debug_name_ << ": not synced, assuming doesn't match";
return false;
}
@@ -803,7 +862,7 @@ bool ProfileSyncServiceHarness::MatchesOtherClient(
<< ": common types are "
<< syncable::ModelTypeSetToString(intersection_types);
- if (!intersection_types.empty() && !partner->IsSynced()) {
+ if (!intersection_types.empty() && !partner->IsFullySynced()) {
VLOG(2) << "non-empty common types and "
<< partner->profile_debug_name_ << " isn't synced";
return false;
@@ -872,7 +931,7 @@ bool ProfileSyncServiceHarness::EnableSyncForDatatype(
synced_datatypes.insert(syncable::ModelTypeFromInt(datatype));
service()->OnUserChoseDatatypes(false, synced_datatypes);
- if (AwaitSyncCycleCompletion("Datatype configuration.")) {
+ if (AwaitFullSyncCompletion("Datatype configuration.")) {
VLOG(1) << "EnableSyncForDatatype(): Enabled sync for datatype "
<< syncable::ModelTypeToString(datatype)
<< " on " << profile_debug_name_ << ".";
@@ -905,7 +964,7 @@ bool ProfileSyncServiceHarness::DisableSyncForDatatype(
synced_datatypes.erase(it);
service()->OnUserChoseDatatypes(false, synced_datatypes);
- if (AwaitSyncCycleCompletion("Datatype reconfiguration.")) {
+ if (AwaitFullSyncCompletion("Datatype reconfiguration.")) {
VLOG(1) << "DisableSyncForDatatype(): Disabled sync for datatype "
<< syncable::ModelTypeToString(datatype)
<< " on " << profile_debug_name_ << ".";
@@ -935,7 +994,7 @@ bool ProfileSyncServiceHarness::EnableSyncForAllDatatypes() {
synced_datatypes.insert(syncable::ModelTypeFromInt(i));
}
service()->OnUserChoseDatatypes(true, synced_datatypes);
- if (AwaitSyncCycleCompletion("Datatype reconfiguration.")) {
+ if (AwaitFullSyncCompletion("Datatype reconfiguration.")) {
VLOG(1) << "EnableSyncForAllDatatypes(): Enabled sync for all datatypes on "
<< profile_debug_name_ << ".";
return true;
@@ -1035,7 +1094,7 @@ bool ProfileSyncServiceHarness::WaitForTypeEncryption(
// sub-expressions. See crbug.com/95619.
// TODO(rlarocque): Figure out a less brittle way of detecting this.
if (IsTypeEncrypted(type) &&
- IsSynced() &&
+ IsFullySynced() &&
GetLastSessionSnapshot()->num_conflicting_updates == 0) {
// Encryption is already complete for |type|; do not wait.
return true;
« no previous file with comments | « chrome/browser/sync/profile_sync_service_harness.h ('k') | chrome/browser/sync/profile_sync_service_mock.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698