blob: 92719597e5005673496b2502167d12d8769f2893 [file] [log] [blame]
// Copyright (c) 2011 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "base/macros.h"
#include "base/strings/stringprintf.h"
#include "base/test/metrics/histogram_tester.h"
#include "base/values.h"
#include "build/build_config.h"
#include "chrome/browser/sync/test/integration/preferences_helper.h"
#include "chrome/browser/sync/test/integration/profile_sync_service_harness.h"
#include "chrome/browser/sync/test/integration/sync_test.h"
#include "chrome/browser/sync/test/integration/updated_progress_marker_checker.h"
#include "chrome/common/pref_names.h"
#include "components/pref_registry/pref_registry_syncable.h"
#include "components/prefs/json_pref_store.h"
#include "components/prefs/pref_service.h"
#include "components/sync/driver/profile_sync_service.h"
#include "testing/gmock/include/gmock/gmock.h"
using preferences_helper::BooleanPrefMatches;
using preferences_helper::BuildPrefStoreFromPrefsFile;
using preferences_helper::ChangeBooleanPref;
using preferences_helper::GetRegistry;
using user_prefs::PrefRegistrySyncable;
using testing::Eq;
using testing::NotNull;
namespace {
class SingleClientPreferencesSyncTest : public SyncTest {
public:
SingleClientPreferencesSyncTest() : SyncTest(SINGLE_CLIENT) {}
~SingleClientPreferencesSyncTest() override {}
private:
DISALLOW_COPY_AND_ASSIGN(SingleClientPreferencesSyncTest);
};
IN_PROC_BROWSER_TEST_F(SingleClientPreferencesSyncTest, Sanity) {
ASSERT_TRUE(SetupSync()) << "SetupSync() failed.";
ASSERT_TRUE(BooleanPrefMatches(prefs::kHomePageIsNewTabPage));
ChangeBooleanPref(0, prefs::kHomePageIsNewTabPage);
ASSERT_TRUE(UpdatedProgressMarkerChecker(GetSyncService(0)).Wait());
EXPECT_TRUE(BooleanPrefMatches(prefs::kHomePageIsNewTabPage));
}
// This test simply verifies that preferences registered after sync started
// get properly synced.
IN_PROC_BROWSER_TEST_F(SingleClientPreferencesSyncTest, LateRegistration) {
ASSERT_TRUE(SetupClients()) << "SetupClients() failed.";
PrefRegistrySyncable* registry = GetRegistry(GetProfile(0));
const std::string pref_name = "testing.my-test-preference";
registry->WhitelistLateRegistrationPrefForSync(pref_name);
ASSERT_TRUE(SetupSync()) << "SetupSync() failed.";
registry->RegisterBooleanPref(
pref_name, true, user_prefs::PrefRegistrySyncable::SYNCABLE_PREF);
// Verify the default is properly used.
EXPECT_TRUE(GetProfile(0)->GetPrefs()->GetBoolean(pref_name));
// Now make a change and verify it gets uploaded.
GetProfile(0)->GetPrefs()->SetBoolean(pref_name, false);
ASSERT_FALSE(GetProfile(0)->GetPrefs()->GetBoolean(pref_name));
EXPECT_TRUE(UpdatedProgressMarkerChecker(GetSyncService(0)).Wait());
GetRegistry(verifier())
->RegisterBooleanPref(pref_name, true,
user_prefs::PrefRegistrySyncable::SYNCABLE_PREF);
EXPECT_FALSE(BooleanPrefMatches(pref_name.c_str()));
}
// Flaky on Windows. https://crbug.com/930482
#if defined(OS_WIN)
#define MAYBE_ShouldRemoveBadDataWhenRegistering \
DISABLED_ShouldRemoveBadDataWhenRegistering
#else
#define MAYBE_ShouldRemoveBadDataWhenRegistering \
ShouldRemoveBadDataWhenRegistering
#endif
IN_PROC_BROWSER_TEST_F(SingleClientPreferencesSyncTest,
MAYBE_ShouldRemoveBadDataWhenRegistering) {
// Populate the data store with data of type boolean but register as string.
SetPreexistingPreferencesFileContents(
0, "{\"testing\":{\"my-test-preference\":true}}");
ASSERT_TRUE(SetupClients()) << "SetupClients() failed.";
PrefRegistrySyncable* registry = GetRegistry(GetProfile(0));
registry->RegisterStringPref("testing.my-test-preference", "default-value",
user_prefs::PrefRegistrySyncable::SYNCABLE_PREF);
const PrefService::Preference* preference =
GetProfile(0)->GetPrefs()->FindPreference("testing.my-test-preference");
ASSERT_THAT(preference, NotNull());
EXPECT_THAT(preference->GetType(), Eq(base::Value::Type::STRING));
EXPECT_THAT(preference->GetValue()->GetString(), Eq("default-value"));
// This might actually expose a bug: IsDefaultValue() is looking for the
// the store with highest priority which has a value for the preference's
// name. For this, no type checks are done, and hence this value is not
// recognized as a default value. --> file a bug!
EXPECT_TRUE(preference->IsDefaultValue());
// To verify the bad data has been removed, we read the JSON file from disk.
scoped_refptr<PrefStore> pref_store =
BuildPrefStoreFromPrefsFile(GetProfile(0));
const base::Value* result;
EXPECT_FALSE(pref_store->GetValue("testing.my-test-preference", &result));
}
// Regression test to verify that pagination during GetUpdates() contributes
// properly to UMA histograms.
IN_PROC_BROWSER_TEST_F(SingleClientPreferencesSyncTest,
EmitModelTypeEntityChangeToUma) {
const int kNumEntities = 17;
fake_server_->SetMaxGetUpdatesBatchSize(7);
sync_pb::EntitySpecifics specifics;
for (int i = 0; i < kNumEntities; i++) {
specifics.mutable_preference()->set_name(base::StringPrintf("pref%d", i));
fake_server_->InjectEntity(
syncer::PersistentUniqueClientEntity::CreateFromSpecificsForTesting(
/*non_unique_name=*/"",
/*client_tag=*/specifics.preference().name(), specifics,
/*creation_time=*/0, /*last_modified_time=*/0));
}
base::HistogramTester histogram_tester;
ASSERT_TRUE(SetupSync());
EXPECT_EQ(kNumEntities, histogram_tester.GetBucketCount(
"Sync.ModelTypeEntityChange3.PREFERENCE",
/*REMOTE_INITIAL_UPDATE=*/5));
}
IN_PROC_BROWSER_TEST_F(SingleClientPreferencesSyncTest,
PRE_PersistProgressMarkerOnRestart) {
sync_pb::EntitySpecifics specifics;
specifics.mutable_preference()->set_name("testing.my-test-preference");
fake_server_->InjectEntity(
syncer::PersistentUniqueClientEntity::CreateFromSpecificsForTesting(
/*non_unique_name=*/"",
/*client_tag=*/specifics.preference().name(), specifics,
/*creation_time=*/0,
/*last_modified_time=*/0));
base::HistogramTester histogram_tester;
ASSERT_TRUE(SetupSync());
EXPECT_EQ(1, histogram_tester.GetBucketCount(
"Sync.ModelTypeEntityChange3.PREFERENCE",
/*REMOTE_INITIAL_UPDATE=*/5));
}
IN_PROC_BROWSER_TEST_F(SingleClientPreferencesSyncTest,
PersistProgressMarkerOnRestart) {
sync_pb::EntitySpecifics specifics;
specifics.mutable_preference()->set_name("testing.my-test-preference");
fake_server_->InjectEntity(
syncer::PersistentUniqueClientEntity::CreateFromSpecificsForTesting(
/*non_unique_name=*/"",
/*client_tag=*/specifics.preference().name(), specifics,
/*creation_time=*/0,
/*last_modified_time=*/0));
base::HistogramTester histogram_tester;
ASSERT_TRUE(SetupClients()) << "SetupClients() failed.";
#if defined(CHROMEOS)
// identity::SetRefreshTokenForPrimaryAccount() is needed on ChromeOS in order
// to get a non-empty refresh token on startup.
GetClient(0)->SignInPrimaryAccount();
#endif // defined(CHROMEOS)
ASSERT_TRUE(GetClient(0)->AwaitEngineInitialization());
// After restart, the last sync cycle snapshot should be empty.
// Once a sync request happened (e.g. by a poll), that snapshot is populated.
// We use the following checker to simply wait for an non-empty snapshot.
EXPECT_TRUE(UpdatedProgressMarkerChecker(GetSyncService(0)).Wait());
EXPECT_EQ(0, histogram_tester.GetBucketCount(
"Sync.ModelTypeEntityChange3.PREFERENCE",
/*REMOTE_INITIAL_UPDATE=*/5));
}
} // namespace