Commit 57093a57 authored by Jan Krcal's avatar Jan Krcal Committed by Commit Bot

Revert "Reland "Fix flaky test ServerAddressConvertsToSameLocalAddress""

This reverts commit ba52e783.

Reason for revert: This caused flakiness in the TwoClientAutofillProfileSyncTest.ClientsAddSameProfile test.

Original change's description:
> Reland "Fix flaky test ServerAddressConvertsToSameLocalAddress"
> 
> This is a reland of commit b3873b4d.
> 
> The CL fixes a race condition in production code of autofill profile
> sync bridge by modifying merge logic of the datatype. Previously, the
> logic for dealing with duplicate entities was to always prefer the
> remote one and silently delete the local one. This could end up with
> two clients having a different entry each and the sync server having
> both duplicate entries. The new behavior, introduced in this CL is to
> keep the profile with greater GUID, lexicographically.
> 
> This change should also remove flakiness of one integration test (that
> uncovered the actual issue), so the CL reenables the test.
> 
> The original CL caused flakiness in another integration test since GUIDs
> in that test are randomly attributed. In this reland, we fix this by
> making the expectation on the number of sync deletions depend on which
> one of the test GUIDs is bigger.
> 
> Bug: 917498
> Change-Id: I13994ac5bef8fcae41d37350e08ee80ab90f0916
> Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2002571
> Auto-Submit: Jan Krcal <jkrcal@chromium.org>
> Commit-Queue: Jan Krcal <jkrcal@chromium.org>
> Commit-Queue: Maxim Kolosovskiy <kolos@chromium.org>
> Reviewed-by: Maxim Kolosovskiy <kolos@chromium.org>
> Reviewed-by: Mikel Astiz <mastiz@chromium.org>
> Cr-Commit-Position: refs/heads/master@{#733636}

TBR=kolos@chromium.org,jkrcal@chromium.org,mastiz@chromium.org

Change-Id: Ifad46c8c079b24a07c044b9d6a5ffdc77a439617
No-Presubmit: true
No-Tree-Checks: true
No-Try: true
Bug: 917498
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2013281Reviewed-by: default avatarJan Krcal <jkrcal@chromium.org>
Commit-Queue: Jan Krcal <jkrcal@chromium.org>
Cr-Commit-Position: refs/heads/master@{#733910}
parent 1d0a2056
......@@ -188,6 +188,7 @@ IN_PROC_BROWSER_TEST_F(TwoClientAutofillProfileSyncTest,
LOCAL_DELETION, 0);
}
// Flaky on all platform. See crbug.com/971666
IN_PROC_BROWSER_TEST_F(TwoClientAutofillProfileSyncTest,
AddDuplicateProfiles_OneIsVerified) {
ASSERT_TRUE(SetupClients());
......@@ -209,20 +210,13 @@ IN_PROC_BROWSER_TEST_F(TwoClientAutofillProfileSyncTest,
EXPECT_EQ(verified_origin, GetAllAutoFillProfiles(0)[0]->origin());
EXPECT_EQ(verified_origin, GetAllAutoFillProfiles(1)[0]->origin());
// Among duplicate profiles, sync prefers the one with largest GUID. If
// |profile0| (committed first) has a smaller GUID, client 1 should upload its
// deletion to the server. Otherwise, no deletion should occur.
if (profile1.guid() > profile0.guid()) {
histograms.ExpectBucketCount("Sync.ModelTypeEntityChange3.AUTOFILL_PROFILE",
LOCAL_DELETION, 1);
} else {
histograms.ExpectBucketCount("Sync.ModelTypeEntityChange3.AUTOFILL_PROFILE",
LOCAL_DELETION, 0);
}
}
IN_PROC_BROWSER_TEST_F(TwoClientAutofillProfileSyncTest,
AddDuplicateProfiles_OneAtStart_OtherComesLater) {
IN_PROC_BROWSER_TEST_F(
TwoClientAutofillProfileSyncTest,
AddDuplicateProfiles_OneIsVerified_NonverifiedComesLater) {
ASSERT_TRUE(SetupClients());
base::HistogramTester histograms;
......@@ -231,23 +225,26 @@ IN_PROC_BROWSER_TEST_F(TwoClientAutofillProfileSyncTest,
autofill::test::GetVerifiedProfile(); // I.e. Full + Verified.
std::string verified_origin = profile1.origin();
AddProfile(0, profile0);
// We start by having the verified profile.
AddProfile(1, profile1);
ASSERT_TRUE(SetupSync());
EXPECT_TRUE(AutofillProfileChecker(0, 1).Wait());
EXPECT_EQ(1U, GetAllAutoFillProfiles(0).size());
EXPECT_EQ(verified_origin, GetAllAutoFillProfiles(0)[0]->origin());
EXPECT_EQ(verified_origin, GetAllAutoFillProfiles(1)[0]->origin());
// Add the same (but verified) profile on the other client, afterwards.
AddProfile(1, profile1);
// Add the same (but non-verified) profile on the other client, afterwards.
AddProfile(0, profile0);
EXPECT_TRUE(AutofillProfileChecker(0, 1).Wait());
// The latter addition is caught in deduplication logic in PDM to sync. As a
// result, both clients end up with the non-verified profile.
// The profiles should de-duplicate via sync on both other client, the
// verified one should win.
EXPECT_EQ(1U, GetAllAutoFillProfiles(0).size());
EXPECT_EQ(1U, GetAllAutoFillProfiles(0).size());
EXPECT_NE(verified_origin, GetAllAutoFillProfiles(0)[0]->origin());
EXPECT_NE(verified_origin, GetAllAutoFillProfiles(1)[0]->origin());
EXPECT_EQ(verified_origin, GetAllAutoFillProfiles(0)[0]->origin());
EXPECT_EQ(verified_origin, GetAllAutoFillProfiles(1)[0]->origin());
histograms.ExpectBucketCount("Sync.ModelTypeEntityChange3.AUTOFILL_PROFILE",
LOCAL_DELETION, 0);
......
......@@ -465,7 +465,7 @@ IN_PROC_BROWSER_TEST_F(
// Flaky. http://crbug.com/917498
IN_PROC_BROWSER_TEST_F(TwoClientWalletSyncTest,
ServerAddressConvertsToSameLocalAddress) {
DISABLED_ServerAddressConvertsToSameLocalAddress) {
GetFakeServer()->SetWalletData(
{CreateSyncWalletAddress(/*name=*/"address-1", /*company=*/"Company-1"),
CreateDefaultSyncPaymentsCustomerData()});
......
per-file *sync_bridge*=jkrcal@chromium.org
per-file *sync_bridge*=file://components/sync/OWNERS
per-file autofill_profile_sync_difference_tracker*=jkrcal@chromium.org
per-file autofill_profile_sync_difference_tracker*=file://components/sync/OWNERS
per-file *syncable_service*=jkrcal@chromium.org
per-file *syncable_service*=file://components/sync/OWNERS
per-file *type_controller*=jkrcal@chromium.org
per-file *type_controller*=file://components/sync/OWNERS
......@@ -251,18 +251,13 @@ base::Optional<syncer::ModelError> AutofillProfileSyncBridge::FlushSyncTracker(
base::Unretained(web_data_backend_))));
std::vector<std::unique_ptr<AutofillProfile>> profiles_to_upload_to_sync;
std::vector<std::string> profiles_to_delete_from_sync;
RETURN_IF_ERROR(tracker->FlushToSync(&profiles_to_upload_to_sync,
&profiles_to_delete_from_sync));
RETURN_IF_ERROR(tracker->FlushToSync(&profiles_to_upload_to_sync));
for (const std::unique_ptr<AutofillProfile>& entry :
profiles_to_upload_to_sync) {
change_processor()->Put(GetStorageKeyFromAutofillProfile(*entry),
CreateEntityDataFromAutofillProfile(*entry),
metadata_change_list.get());
}
for (const std::string& storage_key : profiles_to_delete_from_sync) {
change_processor()->Delete(storage_key, metadata_change_list.get());
}
return static_cast<syncer::SyncMetadataStoreChangeList*>(
metadata_change_list.get())
......
......@@ -64,11 +64,6 @@ AutofillProfileSyncDifferenceTracker::IncorporateRemoteProfile(
}
// Check if profile appears under a different storage key to be de-duplicated.
// TODO(crbug.com/1043683): Deal with rare cases when an remote update
// contains several exact duplicates (with different guids). We should not
// only search in local only entries but also in |update_to_local_| and
// |add_to_local_|. Likely needs a bit of refactoring to make the resulting
// code easy to understand.
for (const auto& pair : *GetLocalOnlyEntries()) {
const std::string& local_storage_key = pair.first;
const AutofillProfile& local = *pair.second;
......@@ -76,76 +71,30 @@ AutofillProfileSyncDifferenceTracker::IncorporateRemoteProfile(
// Look for exact duplicates, compare only profile contents (and
// ignore origin and language code in comparison).
if (local.Compare(*remote) == 0) {
// A duplicate found: keep the version with the bigger storage key.
// We found a duplicate, we keep the new (remote) one and delete the
// local one.
DVLOG(2)
<< "[AUTOFILL SYNC] The profile "
<< base::UTF16ToUTF8(local.GetRawInfo(NAME_FIRST))
<< base::UTF16ToUTF8(local.GetRawInfo(NAME_LAST))
<< " already exists with a different storage key; keep the bigger "
<< (remote_storage_key > local_storage_key ? "remote" : "local")
<< " key " << std::max(remote_storage_key, local_storage_key)
<< " and delete the smaller key "
<< std::min(remote_storage_key, local_storage_key);
if (remote_storage_key > local_storage_key) {
// We keep the remote entity and delete the local one.
<< " already exists with a different storage key; keep the remote key"
<< remote_storage_key << " and delete the local key "
<< local_storage_key;
// Ensure that a verified profile can never revert back to an unverified
// one. In such a case, take over the old origin for the new entry.
// one. In such a case, take over the local origin for the new (remote)
// entry.
if (local.IsVerified() && !remote->IsVerified()) {
remote->set_origin(local.origin());
// Save a copy of the remote profile also to sync.
save_to_sync_.push_back(std::make_unique<AutofillProfile>(*remote));
}
add_to_local_.push_back(std::move(remote));
// Deleting from sync is a no-op if it is local-only so far.
// There are a few ways how a synced local entry A could theoretically
// receive a remote duplicate B with a larger GUID:
// 1) Remote entity B got uploaded by another client through initial
// sync. That client thus also knew about A and issued a deletion of
// A at the same time. This client (if receiving creation of B
// first) resolves the conflict in the same way and re-issues the
// deletion of A. In most cases the redundant deletion does not even
// get sent as the processor already knows A got deleted remotely.
// 2) Remote entity B got uploaded by another client through race
// condition (i.e. not knowing about A, yet). In practice, this only
// happens when two clients simultaneously convert a server profile
// into local profiles. If the other client goes offline before
// receiving A, this client is responsible for deleting A from the
// server and thus must issue a deletion. (In most cases, the other
// client does not go offline and thus both clients issue a deletion
// of A independently).
// 3) (a paranoid case) Remote entity B got uploaded by another client
// by an error, i.e. already as a duplicate given their local state.
// Through standard flows, it should be impossible (duplicates are
// cought early in PDM code so such a change attempt does not even
// propagate to the sync bridge). Still, it's good to treat this
// case here for robustness.
delete_from_sync_.insert(local_storage_key);
// Delete the local profile that gets replaced by |remote|.
DeleteFromLocal(local_storage_key);
} else {
// We keep the local entity and delete the remote one.
// Ensure that a verified profile can never revert back to an unverified
// one. In such a case, modify the origin and re-upload. Otherwise,
// there's no need to upload it: either is was already uploaded before
// (if this is incremental sync) or we'll upload it with all the
// remaining data in GetLocalOnlyEntries (if this is an initial sync).
if (remote->IsVerified() && !local.IsVerified()) {
auto modified_local = std::make_unique<AutofillProfile>(local);
modified_local->set_origin(remote->origin());
update_to_local_.push_back(
std::make_unique<AutofillProfile>(*modified_local));
save_to_sync_.push_back(std::move(modified_local));
// The local entity is already marked for upload so it is not local
// only anymore (we do not want to upload it once again while flushing
// if this is initial sync).
GetLocalOnlyEntries()->erase(local_storage_key);
}
delete_from_sync_.insert(remote_storage_key);
}
return base::nullopt;
break;
}
}
// If no duplicate was found, just add the remote profile.
add_to_local_.push_back(std::move(remote));
return base::nullopt;
}
......@@ -183,14 +132,10 @@ Optional<ModelError> AutofillProfileSyncDifferenceTracker::FlushToLocal(
}
Optional<ModelError> AutofillProfileSyncDifferenceTracker::FlushToSync(
std::vector<std::unique_ptr<AutofillProfile>>* profiles_to_upload_to_sync,
std::vector<std::string>* profiles_to_delete_from_sync) {
std::vector<std::unique_ptr<AutofillProfile>>* profiles_to_upload_to_sync) {
for (std::unique_ptr<AutofillProfile>& entry : save_to_sync_) {
profiles_to_upload_to_sync->push_back(std::move(entry));
}
for (const std::string& entry : delete_from_sync_) {
profiles_to_delete_from_sync->push_back(std::move(entry));
}
return base::nullopt;
}
......@@ -255,11 +200,9 @@ AutofillProfileInitialSyncDifferenceTracker::IncorporateRemoteDelete(
}
Optional<ModelError> AutofillProfileInitialSyncDifferenceTracker::FlushToSync(
std::vector<std::unique_ptr<AutofillProfile>>* profiles_to_upload_to_sync,
std::vector<std::string>* profiles_to_delete_from_sync) {
std::vector<std::unique_ptr<AutofillProfile>>* profiles_to_upload_to_sync) {
// First, flush standard updates to sync.
AutofillProfileSyncDifferenceTracker::FlushToSync(
profiles_to_upload_to_sync, profiles_to_delete_from_sync);
AutofillProfileSyncDifferenceTracker::FlushToSync(profiles_to_upload_to_sync);
// For initial sync, we additionally need to upload all local only entries.
if (!GetLocalOnlyEntries()) {
......
......@@ -50,12 +50,11 @@ class AutofillProfileSyncDifferenceTracker {
base::OnceClosure autofill_changes_callback);
// Writes into |profiles_to_upload_to_sync| all autofill profiles to be sent
// to the sync server, and into |profiles_to_delete_from_sync| the storage
// keys of all profiles to be deleted from the server. After flushing, no
// further remote changes should get incorporated.
// to the sync server. After flushing, not further remote changes should get
// incorporated.
virtual base::Optional<syncer::ModelError> FlushToSync(
std::vector<std::unique_ptr<AutofillProfile>>* profiles_to_upload_to_sync,
std::vector<std::string>* profiles_to_delete_from_sync);
std::vector<std::unique_ptr<AutofillProfile>>*
profiles_to_upload_to_sync);
protected:
// If the entry is found, |entry| will be return, otherwise base::nullopt is
......@@ -90,7 +89,7 @@ class AutofillProfileSyncDifferenceTracker {
// We use unique_ptrs for storing AutofillProfile to avoid unnecessary copies.
// Local data, mapped by storage key. Use GetLocalOnlyEntries() to access it.
// Local data, mapped by storage key. Use unique_to_local() to access it.
std::map<std::string, std::unique_ptr<AutofillProfile>> local_only_entries_;
// Contain changes (originating from sync) that need to be saved to the local
......@@ -99,13 +98,9 @@ class AutofillProfileSyncDifferenceTracker {
std::vector<std::unique_ptr<AutofillProfile>> add_to_local_;
std::vector<std::unique_ptr<AutofillProfile>> update_to_local_;
// Contains data for entries that existed on both sync and local sides
// Contains merged data for entries that existed on both sync and local sides
// and need to be saved back to sync.
std::vector<std::unique_ptr<AutofillProfile>> save_to_sync_;
// Contains storage keys for entries that existed on both sync and local
// sides and need to be deleted from sync (because the conflict resolution
// preferred the local copies).
std::set<std::string> delete_from_sync_;
private:
DISALLOW_COPY_AND_ASSIGN(AutofillProfileSyncDifferenceTracker);
......@@ -121,8 +116,8 @@ class AutofillProfileInitialSyncDifferenceTracker
const std::string& storage_key) override;
base::Optional<syncer::ModelError> FlushToSync(
std::vector<std::unique_ptr<AutofillProfile>>* profiles_to_upload_to_sync,
std::vector<std::string>* profiles_to_delete_from_sync) override;
std::vector<std::unique_ptr<AutofillProfile>>* profiles_to_upload_to_sync)
override;
// Performs an additional pass through remote entries incorporated from sync
// to find any similarities with local entries. Should be run after all
......
......@@ -30,18 +30,13 @@ using testing::ElementsAre;
using testing::IsEmpty;
// Some guids for testing.
const char kSmallerGuid[] = "EDC609ED-7EEE-4F27-B00C-423242A9C44A";
const char kBiggerGuid[] = "EDC609ED-7EEE-4F27-B00C-423242A9C44B";
const char kGuidA[] = "EDC609ED-7EEE-4F27-B00C-423242A9C44A";
const char kGuidB[] = "EDC609ED-7EEE-4F27-B00C-423242A9C44B";
const char kHttpOrigin[] = "http://www.example.com/";
const char kHttpsOrigin[] = "https://www.example.com/";
const char kLocaleString[] = "en-US";
const base::Time kJune2017 = base::Time::FromDoubleT(1497552271);
struct UpdatesToSync {
std::vector<AutofillProfile> profiles_to_upload_to_sync;
std::vector<std::string> profiles_to_delete_from_sync;
};
} // namespace
class AutofillProfileSyncDifferenceTrackerTestBase : public testing::Test {
......@@ -70,26 +65,24 @@ class AutofillProfileSyncDifferenceTrackerTestBase : public testing::Test {
std::make_unique<AutofillProfile>(profile)));
}
UpdatesToSync FlushToSync() {
std::vector<AutofillProfile> FlushAndReturnProfilesToUploadToSync() {
EXPECT_EQ(base::nullopt,
tracker()->FlushToLocal(
/*autofill_changes_callback=*/base::DoNothing()));
UpdatesToSync updates;
std::vector<std::unique_ptr<AutofillProfile>> vector_of_unique_ptrs;
EXPECT_EQ(base::nullopt,
tracker()->FlushToSync(
/*profiles_to_upload_to_sync=*/&vector_of_unique_ptrs,
/*profiles_to_delete_from_sync=*/&updates
.profiles_to_delete_from_sync));
/*profiles_to_upload_to_sync=*/&vector_of_unique_ptrs));
// Copy all the elements by value so that we have a vector that is easier to
// work with in the test.
std::vector<AutofillProfile> vector_of_values;
for (const std::unique_ptr<AutofillProfile>& entry :
vector_of_unique_ptrs) {
updates.profiles_to_upload_to_sync.push_back(*entry);
vector_of_values.push_back(*entry);
}
return updates;
return vector_of_values;
}
std::vector<AutofillProfile> GetAllLocalData() {
......@@ -137,69 +130,63 @@ class AutofillProfileSyncDifferenceTrackerTest
TEST_F(AutofillProfileSyncDifferenceTrackerTest,
IncorporateRemoteProfileShouldOverwriteProfileWithSameKey) {
AutofillProfile local = AutofillProfile(kSmallerGuid, kHttpOrigin);
AutofillProfile local = AutofillProfile(kGuidA, kHttpOrigin);
local.SetRawInfo(NAME_FIRST, ASCIIToUTF16("John"));
AddAutofillProfilesToTable({local});
// The remote profile is completely different but it has the same key.
AutofillProfile remote = AutofillProfile(kSmallerGuid, kHttpsOrigin);
AutofillProfile remote = AutofillProfile(kGuidA, kHttpsOrigin);
remote.SetRawInfo(NAME_FIRST, ASCIIToUTF16("Tom"));
IncorporateRemoteProfile(remote);
// Nothing gets uploaded to sync and the remote profile wins.
UpdatesToSync updates = FlushToSync();
EXPECT_THAT(updates.profiles_to_upload_to_sync, IsEmpty());
EXPECT_THAT(updates.profiles_to_delete_from_sync, IsEmpty());
EXPECT_THAT(FlushAndReturnProfilesToUploadToSync(), IsEmpty());
EXPECT_THAT(GetAllLocalData(), ElementsAre(remote));
}
TEST_F(AutofillProfileSyncDifferenceTrackerTest,
IncorporateRemoteProfileShouldOverwriteUnverifiedProfileByVerified) {
AutofillProfile local = AutofillProfile(kSmallerGuid, kHttpsOrigin);
AutofillProfile local = AutofillProfile(kGuidA, kHttpsOrigin);
local.SetRawInfo(NAME_FIRST, ASCIIToUTF16("John"));
AddAutofillProfilesToTable({local});
// The remote profile has the same key but it is not verified.
AutofillProfile remote = AutofillProfile(kSmallerGuid, kSettingsOrigin);
AutofillProfile remote = AutofillProfile(kGuidA, kSettingsOrigin);
remote.SetRawInfo(NAME_FIRST, ASCIIToUTF16("Tom"));
IncorporateRemoteProfile(remote);
// Nothing gets uploaded to sync and the local profile wins.
UpdatesToSync updates = FlushToSync();
EXPECT_THAT(updates.profiles_to_upload_to_sync, IsEmpty());
EXPECT_THAT(updates.profiles_to_delete_from_sync, IsEmpty());
EXPECT_THAT(FlushAndReturnProfilesToUploadToSync(), IsEmpty());
EXPECT_THAT(GetAllLocalData(), ElementsAre(remote));
}
TEST_F(AutofillProfileSyncDifferenceTrackerTest,
IncorporateRemoteProfileShouldNotOverwriteVerifiedProfileByUnverified) {
AutofillProfile local = AutofillProfile(kSmallerGuid, kSettingsOrigin);
AutofillProfile local = AutofillProfile(kGuidA, kSettingsOrigin);
local.SetRawInfo(NAME_FIRST, ASCIIToUTF16("John"));
AddAutofillProfilesToTable({local});
// The remote profile has the same key but it is not verified.
AutofillProfile remote = AutofillProfile(kSmallerGuid, kHttpsOrigin);
AutofillProfile remote = AutofillProfile(kGuidA, kHttpsOrigin);
remote.SetRawInfo(NAME_FIRST, ASCIIToUTF16("Tom"));
IncorporateRemoteProfile(remote);
// Nothing gets uploaded to sync and the local profile wins.
UpdatesToSync updates = FlushToSync();
EXPECT_THAT(updates.profiles_to_upload_to_sync, IsEmpty());
EXPECT_THAT(updates.profiles_to_delete_from_sync, IsEmpty());
EXPECT_THAT(FlushAndReturnProfilesToUploadToSync(), IsEmpty());
EXPECT_THAT(GetAllLocalData(), ElementsAre(local));
}
TEST_F(AutofillProfileSyncDifferenceTrackerTest,
IncorporateRemoteProfileShouldNotOverwriteFullNameByEmptyString) {
AutofillProfile local = AutofillProfile(kSmallerGuid, kHttpOrigin);
AutofillProfile local = AutofillProfile(kGuidA, kHttpOrigin);
local.SetRawInfo(NAME_FULL, ASCIIToUTF16("John"));
AddAutofillProfilesToTable({local});
// The remote profile has the same key.
AutofillProfile remote = AutofillProfile(kSmallerGuid, kHttpsOrigin);
AutofillProfile remote = AutofillProfile(kGuidA, kHttpsOrigin);
remote.SetRawInfo(ADDRESS_HOME_STREET_ADDRESS, ASCIIToUTF16("2 2st st"));
AutofillProfile merged(remote);
......@@ -209,46 +196,40 @@ TEST_F(AutofillProfileSyncDifferenceTrackerTest,
// Nothing gets uploaded to sync and the remote profile wins except for the
// full name.
UpdatesToSync updates = FlushToSync();
EXPECT_THAT(updates.profiles_to_upload_to_sync, IsEmpty());
EXPECT_THAT(updates.profiles_to_delete_from_sync, IsEmpty());
EXPECT_THAT(FlushAndReturnProfilesToUploadToSync(), IsEmpty());
EXPECT_THAT(GetAllLocalData(), ElementsAre(merged));
}
TEST_F(
AutofillProfileSyncDifferenceTrackerTest,
IncorporateRemoteProfileShouldKeepRemoteKeyWhenMergingDuplicateProfileWithBiggerKey) {
AutofillProfile local = AutofillProfile(kSmallerGuid, kHttpOrigin);
TEST_F(AutofillProfileSyncDifferenceTrackerTest,
IncorporateRemoteProfileShouldMergeIdenticalProfilesWithDifferentKeys) {
AutofillProfile local = AutofillProfile(kGuidA, kHttpOrigin);
local.SetRawInfo(NAME_FIRST, ASCIIToUTF16("John"));
local.SetRawInfo(ADDRESS_HOME_STREET_ADDRESS, ASCIIToUTF16("1 1st st"));
AddAutofillProfilesToTable({local});
// The remote profile is identical to the local one, except that the guids and
// origins are different.
AutofillProfile remote = AutofillProfile(kBiggerGuid, kHttpsOrigin);
AutofillProfile remote = AutofillProfile(kGuidB, kHttpsOrigin);
remote.SetRawInfo(NAME_FIRST, ASCIIToUTF16("John"));
remote.SetRawInfo(ADDRESS_HOME_STREET_ADDRESS, ASCIIToUTF16("1 1st st"));
IncorporateRemoteProfile(remote);
// Nothing gets uploaded to sync and the remote profile wins.
UpdatesToSync updates = FlushToSync();
EXPECT_THAT(updates.profiles_to_upload_to_sync, IsEmpty());
EXPECT_THAT(updates.profiles_to_delete_from_sync,
ElementsAre(std::string(kSmallerGuid)));
EXPECT_THAT(FlushAndReturnProfilesToUploadToSync(), IsEmpty());
EXPECT_THAT(GetAllLocalData(), ElementsAre(remote));
}
TEST_F(
AutofillProfileSyncDifferenceTrackerTest,
IncorporateRemoteProfileShouldKeepRemoteKeyAndLocalOriginWhenMergingDuplicateProfileWithBiggerKey) {
AutofillProfile local = AutofillProfile(kSmallerGuid, kSettingsOrigin);
IncorporateRemoteProfileShouldMergeIdenticalProfilesWithDifferentKeysButKeepVerifiedOrigin) {
AutofillProfile local = AutofillProfile(kGuidA, kSettingsOrigin);
local.SetRawInfo(NAME_FIRST, ASCIIToUTF16("John"));
local.SetRawInfo(ADDRESS_HOME_STREET_ADDRESS, ASCIIToUTF16("1 1st st"));
AddAutofillProfilesToTable({local});
// The remote profile has the same key.
AutofillProfile remote = AutofillProfile(kBiggerGuid, kHttpsOrigin);
AutofillProfile remote = AutofillProfile(kGuidB, kHttpsOrigin);
remote.SetRawInfo(NAME_FIRST, ASCIIToUTF16("John"));
remote.SetRawInfo(ADDRESS_HOME_STREET_ADDRESS, ASCIIToUTF16("1 1st st"));
......@@ -259,61 +240,7 @@ TEST_F(
// Nothing gets uploaded to sync and the remote profile wins except for the
// full name.
UpdatesToSync updates = FlushToSync();
EXPECT_THAT(updates.profiles_to_upload_to_sync, ElementsAre(merged));
EXPECT_THAT(updates.profiles_to_delete_from_sync,
ElementsAre(std::string(kSmallerGuid)));
EXPECT_THAT(GetAllLocalData(), ElementsAre(merged));
}
TEST_F(
AutofillProfileSyncDifferenceTrackerTest,
IncorporateRemoteProfileShouldKeepLocalKeyWhenMergingDuplicateProfileWithSmallerKey) {
AutofillProfile local = AutofillProfile(kBiggerGuid, kHttpOrigin);
local.SetRawInfo(NAME_FIRST, ASCIIToUTF16("John"));
local.SetRawInfo(ADDRESS_HOME_STREET_ADDRESS, ASCIIToUTF16("1 1st st"));
AddAutofillProfilesToTable({local});
// The remote profile is identical to the local one, except that the guids and
// origins are different.
AutofillProfile remote = AutofillProfile(kSmallerGuid, kHttpsOrigin);
remote.SetRawInfo(NAME_FIRST, ASCIIToUTF16("John"));
remote.SetRawInfo(ADDRESS_HOME_STREET_ADDRESS, ASCIIToUTF16("1 1st st"));
IncorporateRemoteProfile(remote);
// Nothing gets uploaded to sync and the remote profile wins.
UpdatesToSync updates = FlushToSync();
EXPECT_THAT(updates.profiles_to_upload_to_sync, IsEmpty());
EXPECT_THAT(updates.profiles_to_delete_from_sync,
ElementsAre(std::string(kSmallerGuid)));
EXPECT_THAT(GetAllLocalData(), ElementsAre(local));
}
TEST_F(
AutofillProfileSyncDifferenceTrackerTest,
IncorporateRemoteProfileShouldKeepLocalKeyAndRemoteOriginWhenMergingDuplicateProfileWithSmallerKey) {
AutofillProfile local = AutofillProfile(kBiggerGuid, kHttpsOrigin);
local.SetRawInfo(NAME_FIRST, ASCIIToUTF16("John"));
local.SetRawInfo(ADDRESS_HOME_STREET_ADDRESS, ASCIIToUTF16("1 1st st"));
AddAutofillProfilesToTable({local});
// The remote profile has the same key.
AutofillProfile remote = AutofillProfile(kSmallerGuid, kSettingsOrigin);
remote.SetRawInfo(NAME_FIRST, ASCIIToUTF16("John"));
remote.SetRawInfo(ADDRESS_HOME_STREET_ADDRESS, ASCIIToUTF16("1 1st st"));
AutofillProfile merged(local);
merged.set_origin(kSettingsOrigin);
IncorporateRemoteProfile(remote);
// Nothing gets uploaded to sync and the remote profile wins except for the
// full name.
UpdatesToSync updates = FlushToSync();
EXPECT_THAT(updates.profiles_to_upload_to_sync, ElementsAre(merged));
EXPECT_THAT(updates.profiles_to_delete_from_sync,
ElementsAre(std::string(kSmallerGuid)));
EXPECT_THAT(FlushAndReturnProfilesToUploadToSync(), ElementsAre(merged));
EXPECT_THAT(GetAllLocalData(), ElementsAre(merged));
}
......@@ -328,10 +255,10 @@ TEST_F(AutofillProfileSyncDifferenceTrackerTest,
TEST_F(AutofillProfileSyncDifferenceTrackerTest,
FlushToLocalShouldCallbackWhenProfileDeleted) {
AutofillProfile local = AutofillProfile(kSmallerGuid, kSettingsOrigin);
AutofillProfile local = AutofillProfile(kGuidA, kSettingsOrigin);
AddAutofillProfilesToTable({local});
tracker()->IncorporateRemoteDelete(kSmallerGuid);
tracker()->IncorporateRemoteDelete(kGuidA);
MockCallback<base::OnceClosure> autofill_changes_callback;
EXPECT_CALL(autofill_changes_callback, Run()).Times(1);
......@@ -344,7 +271,7 @@ TEST_F(AutofillProfileSyncDifferenceTrackerTest,
TEST_F(AutofillProfileSyncDifferenceTrackerTest,
FlushToLocalShouldCallbackWhenProfileAdded) {
AutofillProfile remote = AutofillProfile(kSmallerGuid, kSettingsOrigin);
AutofillProfile remote = AutofillProfile(kGuidA, kSettingsOrigin);
IncorporateRemoteProfile(remote);
MockCallback<base::OnceClosure> autofill_changes_callback;
......@@ -358,10 +285,10 @@ TEST_F(AutofillProfileSyncDifferenceTrackerTest,
TEST_F(AutofillProfileSyncDifferenceTrackerTest,
FlushToLocalShouldCallbackWhenProfileUpdated) {
AutofillProfile local = AutofillProfile(kSmallerGuid, kHttpsOrigin);
AutofillProfile local = AutofillProfile(kGuidA, kHttpsOrigin);
AddAutofillProfilesToTable({local});
AutofillProfile remote = AutofillProfile(kSmallerGuid, kHttpsOrigin);
AutofillProfile remote = AutofillProfile(kGuidA, kHttpsOrigin);
remote.SetRawInfo(ADDRESS_HOME_STREET_ADDRESS, ASCIIToUTF16("1 1st st"));
IncorporateRemoteProfile(remote);
......@@ -370,7 +297,7 @@ TEST_F(AutofillProfileSyncDifferenceTrackerTest,
EXPECT_EQ(base::nullopt,
tracker()->FlushToLocal(autofill_changes_callback.Get()));
// On top of that, the profile with key kSmallerGuid should also get updated.
// On top of that, the profile with key kGuidA should also get updated.
EXPECT_THAT(GetAllLocalData(), ElementsAre(remote));
}
......@@ -397,13 +324,13 @@ class AutofillProfileInitialSyncDifferenceTrackerTest
TEST_F(AutofillProfileInitialSyncDifferenceTrackerTest,
MergeSimilarEntriesForInitialSyncShouldSyncUpChanges) {
AutofillProfile local = AutofillProfile(kSmallerGuid, kHttpOrigin);
AutofillProfile local = AutofillProfile(kGuidA, kHttpOrigin);
local.SetRawInfo(ADDRESS_HOME_STREET_ADDRESS, ASCIIToUTF16("1 1st st"));
local.set_use_count(27);
AddAutofillProfilesToTable({local});
// The remote profile matches the local one (except for origin and use count).
AutofillProfile remote = AutofillProfile(kBiggerGuid, kHttpsOrigin);
AutofillProfile remote = AutofillProfile(kGuidB, kHttpsOrigin);
remote.SetRawInfo(ADDRESS_HOME_STREET_ADDRESS, ASCIIToUTF16("1 1st st"));
remote.SetRawInfo(COMPANY_NAME, ASCIIToUTF16("Frobbers, Inc."));
remote.set_use_count(13);
......@@ -419,21 +346,19 @@ TEST_F(AutofillProfileInitialSyncDifferenceTrackerTest,
MergeSimilarEntriesForInitialSync();
// The merged profile needs to get uploaded back to sync and stored locally.
UpdatesToSync updates = FlushToSync();
EXPECT_THAT(updates.profiles_to_upload_to_sync, ElementsAre(merged));
EXPECT_THAT(updates.profiles_to_delete_from_sync, IsEmpty());
EXPECT_THAT(FlushAndReturnProfilesToUploadToSync(), ElementsAre(merged));
EXPECT_THAT(GetAllLocalData(), ElementsAre(merged));
}
TEST_F(AutofillProfileInitialSyncDifferenceTrackerTest,
MergeSimilarEntriesForInitialSyncShouldNotSyncUpWhenNotNeeded) {
AutofillProfile local = AutofillProfile(kSmallerGuid, kHttpOrigin);
AutofillProfile local = AutofillProfile(kGuidA, kHttpOrigin);
local.SetRawInfo(ADDRESS_HOME_STREET_ADDRESS, ASCIIToUTF16("1 1st st"));
local.set_use_count(13);
AddAutofillProfilesToTable({local});
// The remote profile matches the local one and has some additional data.
AutofillProfile remote = AutofillProfile(kBiggerGuid, kHttpOrigin);
AutofillProfile remote = AutofillProfile(kGuidB, kHttpOrigin);
remote.SetRawInfo(ADDRESS_HOME_STREET_ADDRESS, ASCIIToUTF16("1 1st st"));
remote.SetRawInfo(COMPANY_NAME, ASCIIToUTF16("Frobbers, Inc."));
// Merging two profile takes their max use count, so use count of 27 is taken.
......@@ -443,21 +368,19 @@ TEST_F(AutofillProfileInitialSyncDifferenceTrackerTest,
MergeSimilarEntriesForInitialSync();
// Nothing gets uploaded to sync and the remote profile wins.
UpdatesToSync updates = FlushToSync();
EXPECT_THAT(updates.profiles_to_upload_to_sync, IsEmpty());
EXPECT_THAT(updates.profiles_to_delete_from_sync, IsEmpty());
EXPECT_THAT(FlushAndReturnProfilesToUploadToSync(), IsEmpty());
EXPECT_THAT(GetAllLocalData(), ElementsAre(remote));
}
TEST_F(AutofillProfileInitialSyncDifferenceTrackerTest,
MergeSimilarEntriesForInitialSyncNotMatchNonsimilarEntries) {
AutofillProfile local = AutofillProfile(kSmallerGuid, kHttpOrigin);
AutofillProfile local = AutofillProfile(kGuidA, kHttpOrigin);
local.SetRawInfo(ADDRESS_HOME_STREET_ADDRESS, ASCIIToUTF16("1 1st st"));
local.SetRawInfo(COMPANY_NAME, ASCIIToUTF16("Frobbers, Inc."));
AddAutofillProfilesToTable({local});
// The remote profile has a different street address.
AutofillProfile remote = AutofillProfile(kBiggerGuid, kHttpOrigin);
AutofillProfile remote = AutofillProfile(kGuidB, kHttpOrigin);
remote.SetRawInfo(ADDRESS_HOME_STREET_ADDRESS, ASCIIToUTF16("2 2st st"));
remote.SetRawInfo(COMPANY_NAME, ASCIIToUTF16("Frobbers, Inc."));
......@@ -466,21 +389,19 @@ TEST_F(AutofillProfileInitialSyncDifferenceTrackerTest,
// The local profile gets uploaded (due to initial sync) and the remote
// profile gets stored locally.
UpdatesToSync updates = FlushToSync();
EXPECT_THAT(updates.profiles_to_upload_to_sync, ElementsAre(local));
EXPECT_THAT(updates.profiles_to_delete_from_sync, IsEmpty());
EXPECT_THAT(FlushAndReturnProfilesToUploadToSync(), ElementsAre(local));
EXPECT_THAT(GetAllLocalData(), ElementsAre(local, remote));
}
TEST_F(AutofillProfileInitialSyncDifferenceTrackerTest,
MergeSimilarEntriesForInitialSyncDoesNotMatchLocalVerifiedEntry) {
// The local entry is verified, should not get merged.
AutofillProfile local = AutofillProfile(kSmallerGuid, kSettingsOrigin);
AutofillProfile local = AutofillProfile(kGuidA, kSettingsOrigin);
local.SetRawInfo(ADDRESS_HOME_STREET_ADDRESS, ASCIIToUTF16("1 1st st"));
AddAutofillProfilesToTable({local});
// The remote profile is similar to the local one.
AutofillProfile remote = AutofillProfile(kBiggerGuid, kHttpOrigin);
AutofillProfile remote = AutofillProfile(kGuidB, kHttpOrigin);
remote.SetRawInfo(ADDRESS_HOME_STREET_ADDRESS, ASCIIToUTF16("1 1st st"));
remote.SetRawInfo(COMPANY_NAME, ASCIIToUTF16("Frobbers, Inc."));
......@@ -489,21 +410,19 @@ TEST_F(AutofillProfileInitialSyncDifferenceTrackerTest,
// The local profile gets uploaded (due to initial sync) and the remote
// profile gets stored locally.
UpdatesToSync updates = FlushToSync();
EXPECT_THAT(updates.profiles_to_upload_to_sync, ElementsAre(local));
EXPECT_THAT(updates.profiles_to_delete_from_sync, IsEmpty());
EXPECT_THAT(FlushAndReturnProfilesToUploadToSync(), ElementsAre(local));
EXPECT_THAT(GetAllLocalData(), ElementsAre(local, remote));
}
TEST_F(AutofillProfileInitialSyncDifferenceTrackerTest,
MergeSimilarEntriesForInitialSyncDoesNotMatchRemoteVerifiedEntry) {
AutofillProfile local = AutofillProfile(kSmallerGuid, kHttpOrigin);
AutofillProfile local = AutofillProfile(kGuidA, kHttpOrigin);
local.SetRawInfo(ADDRESS_HOME_STREET_ADDRESS, ASCIIToUTF16("1 1st st"));
AddAutofillProfilesToTable({local});
// The remote profile is similar to the local one but is verified and thus it
// should not get merged.
AutofillProfile remote = AutofillProfile(kBiggerGuid, kSettingsOrigin);
AutofillProfile remote = AutofillProfile(kGuidB, kSettingsOrigin);
remote.SetRawInfo(ADDRESS_HOME_STREET_ADDRESS, ASCIIToUTF16("1 1st st"));
remote.SetRawInfo(COMPANY_NAME, ASCIIToUTF16("Frobbers, Inc."));
......@@ -512,9 +431,7 @@ TEST_F(AutofillProfileInitialSyncDifferenceTrackerTest,
// The local profile gets uploaded (due to initial sync) and the remote
// profile gets stored locally.
UpdatesToSync updates = FlushToSync();
EXPECT_THAT(updates.profiles_to_upload_to_sync, ElementsAre(local));
EXPECT_THAT(updates.profiles_to_delete_from_sync, IsEmpty());
EXPECT_THAT(FlushAndReturnProfilesToUploadToSync(), ElementsAre(local));
EXPECT_THAT(GetAllLocalData(), ElementsAre(local, remote));
}
......
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