Commit 60d431f2 authored by Mohamed Amir Yosef's avatar Mohamed Amir Yosef Committed by Commit Bot

[Sync] Delete Password Sync Metadata when not readable

Bug: 1044365
Change-Id: I9fd23b258c86f68e01be02f17c49d0adcbe7a1e5
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2064940
Commit-Queue: Mohamed Amir Yosef <mamir@chromium.org>
Reviewed-by: default avatarMikel Astiz <mastiz@chromium.org>
Cr-Commit-Position: refs/heads/master@{#743087}
parent 79fbef22
...@@ -29,6 +29,12 @@ namespace password_manager { ...@@ -29,6 +29,12 @@ namespace password_manager {
namespace { namespace {
// Controls whether we should delete the sync metadata when they aren't
// readable.
const base::Feature kDeletePasswordSyncMetadataWhenNoReadable{
"DeletePasswordSyncMetadataWhenNoReadable",
base::FEATURE_ENABLED_BY_DEFAULT};
// Error values for reading sync metadata. // Error values for reading sync metadata.
// Used in metrics: "PasswordManager.SyncMetadataReadError". These values // Used in metrics: "PasswordManager.SyncMetadataReadError". These values
// are persisted to logs. Entries should not be renumbered and numeric values // are persisted to logs. Entries should not be renumbered and numeric values
...@@ -252,16 +258,24 @@ PasswordSyncBridge::PasswordSyncBridge( ...@@ -252,16 +258,24 @@ PasswordSyncBridge::PasswordSyncBridge(
} else { } else {
batch = password_store_sync_->GetMetadataStore()->GetAllSyncMetadata(); batch = password_store_sync_->GetMetadataStore()->GetAllSyncMetadata();
if (!batch) { if (!batch) {
this->change_processor()->ReportError( if (base::FeatureList::IsEnabled(
{FROM_HERE, kDeletePasswordSyncMetadataWhenNoReadable)) {
"Failed reading passwords metadata from password store."}); // If the metadata cannot be read, it's mostly a persistent error, and
// hence we should drop the metadata to go throw the initial sync flow.
password_store_sync_->GetMetadataStore()->DeleteAllSyncMetadata();
batch = std::make_unique<syncer::MetadataBatch>();
} else {
this->change_processor()->ReportError(
{FROM_HERE,
"Failed reading passwords metadata from password store."});
}
sync_metadata_read_error = SyncMetadataReadError::kReadFailed; sync_metadata_read_error = SyncMetadataReadError::kReadFailed;
} }
} }
base::UmaHistogramEnumeration("PasswordManager.SyncMetadataReadError", base::UmaHistogramEnumeration("PasswordManager.SyncMetadataReadError",
sync_metadata_read_error); sync_metadata_read_error);
if (sync_metadata_read_error == SyncMetadataReadError::kNone) { if (batch) {
this->change_processor()->ModelReadyToSync(std::move(batch)); this->change_processor()->ModelReadyToSync(std::move(batch));
} }
} }
......
...@@ -673,6 +673,24 @@ TEST_F(PasswordSyncBridgeTest, ...@@ -673,6 +673,24 @@ TEST_F(PasswordSyncBridgeTest,
EXPECT_FALSE(error); EXPECT_FALSE(error);
} }
// This tests that if reading sync metadata from the store fails,
// metadata should be deleted and Sync starts without error.
TEST_F(
PasswordSyncBridgeTest,
ShouldMergeSyncRemoteAndLocalPasswordsWithoutErrorWhenMetadataReadFails) {
// Simulate a failed GetAllSyncMetadata() by returning a nullptr.
ON_CALL(*mock_sync_metadata_store_sync(), GetAllSyncMetadata())
.WillByDefault(testing::ReturnNull());
EXPECT_CALL(*mock_sync_metadata_store_sync(), DeleteAllSyncMetadata());
EXPECT_CALL(mock_processor(), ModelReadyToSync(MetadataBatchContains(
/*state=*/syncer::HasNotInitialSyncDone(),
/*entities=*/testing::SizeIs(0))));
auto bridge = std::make_unique<PasswordSyncBridge>(
mock_processor().CreateForwardingProcessor(), mock_password_store_sync(),
base::DoNothing());
}
// This tests that if reading logins from the store fails, // This tests that if reading logins from the store fails,
// ShouldMergeSync() would return an error without crashing. // ShouldMergeSync() would return an error without crashing.
TEST_F(PasswordSyncBridgeTest, TEST_F(PasswordSyncBridgeTest,
......
...@@ -74,6 +74,11 @@ MATCHER(HasInitialSyncDone, "") { ...@@ -74,6 +74,11 @@ MATCHER(HasInitialSyncDone, "") {
return arg.initial_sync_done(); return arg.initial_sync_done();
} }
// Matcher for sync_pb::ModelTypeState: verifies that initial sync is not done.
MATCHER(HasNotInitialSyncDone, "") {
return !arg.initial_sync_done();
}
} // namespace syncer } // namespace syncer
#endif // COMPONENTS_SYNC_TEST_TEST_MATCHERS_H_ #endif // COMPONENTS_SYNC_TEST_TEST_MATCHERS_H_
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment