blob: c3f74e6ab4ae9547c61bfe081c0580c30e37c0a9 [file] [log] [blame]
// Copyright (c) 2012 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 <string>
#include "base/guid.h"
#include "base/macros.h"
#include "base/strings/stringprintf.h"
#include "base/test/metrics/histogram_tester.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_integration_test_util.h"
#include "chrome/browser/sync/test/integration/sync_test.h"
#include "chrome/common/pref_names.h"
#include "components/pref_registry/pref_registry_syncable.h"
#include "components/prefs/pref_service.h"
#include "testing/gmock/include/gmock/gmock.h"
using preferences_helper::BooleanPrefMatches;
using preferences_helper::BuildPrefStoreFromPrefsFile;
using preferences_helper::ChangeBooleanPref;
using preferences_helper::ChangeIntegerPref;
using preferences_helper::ChangeListPref;
using preferences_helper::ChangeStringPref;
using preferences_helper::ClearPref;
using preferences_helper::GetPrefs;
using preferences_helper::GetRegistry;
using testing::Eq;
using user_prefs::PrefRegistrySyncable;
namespace {
class TwoClientPreferencesSyncTest : public SyncTest {
public:
TwoClientPreferencesSyncTest() : SyncTest(TWO_CLIENT) {}
~TwoClientPreferencesSyncTest() override {}
// Needed for AwaitQuiescence().
bool TestUsesSelfNotifications() override { return true; }
private:
DISALLOW_COPY_AND_ASSIGN(TwoClientPreferencesSyncTest);
};
IN_PROC_BROWSER_TEST_F(TwoClientPreferencesSyncTest, E2E_ENABLED(Sanity)) {
ResetSyncForPrimaryAccount();
DisableVerifier();
ASSERT_TRUE(SetupSync()) << "SetupSync() failed.";
// Wait until sync settles before we override the prefs below.
ASSERT_TRUE(AwaitQuiescence());
ASSERT_TRUE(StringPrefMatchChecker(prefs::kHomePage).Wait());
const std::string new_home_page = base::StringPrintf(
"https://example.com/%s", base::GenerateGUID().c_str());
base::HistogramTester histogram_tester;
ChangeStringPref(0, prefs::kHomePage, new_home_page);
ASSERT_TRUE(StringPrefMatchChecker(prefs::kHomePage).Wait());
for (int i = 0; i < num_clients(); ++i) {
ASSERT_EQ(new_home_page, GetPrefs(i)->GetString(prefs::kHomePage));
}
EXPECT_EQ(0, histogram_tester.GetBucketCount(
"Sync.ModelTypeEntityChange3.PREFERENCE",
/*REMOTE_INITIAL_UPDATE=*/5));
// Client 0 may or may not see its own reflection during the test, but at
// least client 1 should have received one update.
EXPECT_NE(0, histogram_tester.GetBucketCount(
"Sync.ModelTypeEntityChange3.PREFERENCE",
/*REMOTE_NON_INITIAL_UPDATE=*/4));
EXPECT_NE(
0U, histogram_tester
.GetAllSamples(
"Sync.NonReflectionUpdateFreshnessPossiblySkewed2.PREFERENCE")
.size());
EXPECT_NE(
0U, histogram_tester
.GetAllSamples("Sync.NonReflectionUpdateFreshnessPossiblySkewed2")
.size());
}
IN_PROC_BROWSER_TEST_F(TwoClientPreferencesSyncTest, E2E_ENABLED(BooleanPref)) {
ResetSyncForPrimaryAccount();
ASSERT_TRUE(SetupSync());
ASSERT_TRUE(BooleanPrefMatchChecker(prefs::kHomePageIsNewTabPage).Wait());
ChangeBooleanPref(0, prefs::kHomePageIsNewTabPage);
ASSERT_TRUE(BooleanPrefMatchChecker(prefs::kHomePageIsNewTabPage).Wait());
}
IN_PROC_BROWSER_TEST_F(TwoClientPreferencesSyncTest,
E2E_ENABLED(Bidirectional)) {
ResetSyncForPrimaryAccount();
ASSERT_TRUE(SetupSync());
ASSERT_TRUE(StringPrefMatchChecker(prefs::kHomePage).Wait());
ChangeStringPref(0, prefs::kHomePage, "http://www.google.com/0");
ASSERT_TRUE(StringPrefMatchChecker(prefs::kHomePage).Wait());
EXPECT_EQ("http://www.google.com/0",
GetPrefs(0)->GetString(prefs::kHomePage));
ChangeStringPref(1, prefs::kHomePage, "http://www.google.com/1");
ASSERT_TRUE(StringPrefMatchChecker(prefs::kHomePage).Wait());
EXPECT_EQ("http://www.google.com/1",
GetPrefs(0)->GetString(prefs::kHomePage));
}
IN_PROC_BROWSER_TEST_F(TwoClientPreferencesSyncTest,
E2E_ENABLED(UnsyncableBooleanPref)) {
ResetSyncForPrimaryAccount();
ASSERT_TRUE(SetupSync());
DisableVerifier();
ASSERT_TRUE(StringPrefMatchChecker(prefs::kHomePage).Wait());
ASSERT_TRUE(BooleanPrefMatchChecker(prefs::kDisableScreenshots).Wait());
// This pref is not syncable.
ChangeBooleanPref(0, prefs::kDisableScreenshots);
// This pref is syncable.
ChangeStringPref(0, prefs::kHomePage, "http://news.google.com");
// Wait until the syncable pref is synced, then expect that the non-syncable
// one is still out of sync.
ASSERT_TRUE(StringPrefMatchChecker(prefs::kHomePage).Wait());
ASSERT_FALSE(BooleanPrefMatches(prefs::kDisableScreenshots));
}
IN_PROC_BROWSER_TEST_F(TwoClientPreferencesSyncTest, E2E_ENABLED(StringPref)) {
ResetSyncForPrimaryAccount();
ASSERT_TRUE(SetupSync());
ASSERT_TRUE(StringPrefMatchChecker(prefs::kHomePage).Wait());
ChangeStringPref(0, prefs::kHomePage, "http://news.google.com");
ASSERT_TRUE(StringPrefMatchChecker(prefs::kHomePage).Wait());
}
IN_PROC_BROWSER_TEST_F(TwoClientPreferencesSyncTest, E2E_ENABLED(ClearPref)) {
ResetSyncForPrimaryAccount();
ASSERT_TRUE(SetupSync());
ChangeStringPref(0, prefs::kHomePage, "http://news.google.com");
ASSERT_TRUE(StringPrefMatchChecker(prefs::kHomePage).Wait());
ClearPref(0, prefs::kHomePage);
ASSERT_TRUE(ClearedPrefMatchChecker(prefs::kHomePage).Wait());
}
IN_PROC_BROWSER_TEST_F(TwoClientPreferencesSyncTest,
E2E_ENABLED(ComplexPrefs)) {
ResetSyncForPrimaryAccount();
ASSERT_TRUE(SetupSync());
ASSERT_TRUE(IntegerPrefMatchChecker(prefs::kRestoreOnStartup).Wait());
ASSERT_TRUE(ListPrefMatchChecker(prefs::kURLsToRestoreOnStartup).Wait());
ChangeIntegerPref(0, prefs::kRestoreOnStartup, 0);
ASSERT_TRUE(IntegerPrefMatchChecker(prefs::kRestoreOnStartup).Wait());
base::ListValue urls;
urls.AppendString("http://www.google.com/");
urls.AppendString("http://www.flickr.com/");
ChangeIntegerPref(0, prefs::kRestoreOnStartup, 4);
ChangeListPref(0, prefs::kURLsToRestoreOnStartup, urls);
ASSERT_TRUE(IntegerPrefMatchChecker(prefs::kRestoreOnStartup).Wait());
ASSERT_TRUE(ListPrefMatchChecker(prefs::kURLsToRestoreOnStartup).Wait());
}
IN_PROC_BROWSER_TEST_F(TwoClientPreferencesSyncTest,
E2E_ENABLED(SingleClientEnabledEncryptionBothChanged)) {
ResetSyncForPrimaryAccount();
ASSERT_TRUE(SetupSync());
ASSERT_TRUE(BooleanPrefMatchChecker(prefs::kHomePageIsNewTabPage).Wait());
ASSERT_TRUE(StringPrefMatchChecker(prefs::kHomePage).Wait());
ASSERT_TRUE(EnableEncryption(0));
ChangeBooleanPref(0, prefs::kHomePageIsNewTabPage);
ChangeStringPref(1, prefs::kHomePage, "http://www.google.com/1");
ASSERT_TRUE(AwaitEncryptionComplete(0));
ASSERT_TRUE(AwaitEncryptionComplete(1));
ASSERT_TRUE(StringPrefMatchChecker(prefs::kHomePage).Wait());
ASSERT_TRUE(BooleanPrefMatchChecker(prefs::kHomePageIsNewTabPage).Wait());
}
IN_PROC_BROWSER_TEST_F(
TwoClientPreferencesSyncTest,
E2E_ENABLED(BothClientsEnabledEncryptionAndChangedMultipleTimes)) {
ResetSyncForPrimaryAccount();
ASSERT_TRUE(SetupSync());
ASSERT_TRUE(BooleanPrefMatchChecker(prefs::kHomePageIsNewTabPage).Wait());
ChangeBooleanPref(0, prefs::kHomePageIsNewTabPage);
ASSERT_TRUE(EnableEncryption(0));
ASSERT_TRUE(EnableEncryption(1));
ASSERT_TRUE(BooleanPrefMatchChecker(prefs::kHomePageIsNewTabPage).Wait());
ASSERT_TRUE(BooleanPrefMatchChecker(prefs::kShowHomeButton).Wait());
ChangeBooleanPref(0, prefs::kShowHomeButton);
ASSERT_TRUE(BooleanPrefMatchChecker(prefs::kShowHomeButton).Wait());
}
// The following tests use lower-level mechanisms to wait for sync cycle
// completions. Those only work reliably with self notifications turned on.
class TwoClientPreferencesSyncTestWithSelfNotifications : public SyncTest {
public:
TwoClientPreferencesSyncTestWithSelfNotifications() : SyncTest(TWO_CLIENT) {}
~TwoClientPreferencesSyncTestWithSelfNotifications() override {}
void SetUp() override {
// If verifiers are enabled, ChangeBooleanPref() and similar methods will
// apply changes to both the specified client and the verifier profile.
// These tests should only apply changes in one client.
DisableVerifier();
SyncTest::SetUp();
}
bool TestUsesSelfNotifications() override { return true; }
private:
DISALLOW_COPY_AND_ASSIGN(TwoClientPreferencesSyncTestWithSelfNotifications);
};
IN_PROC_BROWSER_TEST_F(TwoClientPreferencesSyncTestWithSelfNotifications,
E2E_ENABLED(ShouldKeepLocalDataOnTypeMismatch)) {
ResetSyncForPrimaryAccount();
// Client 1 has type-conflicting data in it's pref file. Verify that incoming
// values from sync of other type do not modify the local state.
SetPreexistingPreferencesFileContents(
1, "{\"testing\":{\"my-test-preference\": \"some-string\"}}");
ASSERT_TRUE(SetupClients()) << "SetupClients() failed.";
constexpr char pref_name[] = "testing.my-test-preference";
GetRegistry(GetProfile(0))
->RegisterBooleanPref(pref_name, false,
user_prefs::PrefRegistrySyncable::SYNCABLE_PREF);
ASSERT_TRUE(SetupSync()) << "SetupSync() failed.";
ChangeBooleanPref(0, pref_name);
ASSERT_THAT(GetPrefs(0)->GetBoolean(pref_name), Eq(true));
GetClient(0)->AwaitMutualSyncCycleCompletion(GetClient(1));
// Verify the value got not stored at client1 (because of type mismatch).
scoped_refptr<PrefStore> pref_store =
BuildPrefStoreFromPrefsFile(GetProfile(1));
const base::Value* result;
ASSERT_TRUE(pref_store->GetValue("testing.my-test-preference", &result));
EXPECT_THAT(result->GetString(), Eq("some-string"));
// Verify reads at client1 get served the default value.
GetRegistry(GetProfile(1))
->RegisterBooleanPref(pref_name, false,
user_prefs::PrefRegistrySyncable::SYNCABLE_PREF);
EXPECT_THAT(GetPrefs(1)->GetBoolean(pref_name), Eq(false));
}
// Verifies that priority synced preferences and regular sycned preferences are
// kept separate.
IN_PROC_BROWSER_TEST_F(TwoClientPreferencesSyncTestWithSelfNotifications,
E2E_ENABLED(ShouldIsolatePriorityPreferences)) {
ResetSyncForPrimaryAccount();
// Register a pref as priority with client0 and regular synced with client1.
ASSERT_TRUE(SetupClients()) << "SetupClients() failed.";
constexpr char pref_name[] = "testing.my-test-preference";
GetRegistry(GetProfile(0))
->RegisterStringPref(
pref_name, "",
user_prefs::PrefRegistrySyncable::SYNCABLE_PRIORITY_PREF);
GetRegistry(GetProfile(1))
->RegisterStringPref(pref_name, "",
user_prefs::PrefRegistrySyncable::SYNCABLE_PREF);
ASSERT_TRUE(SetupSync()) << "SetupSync() failed.";
ChangeStringPref(0, pref_name, "priority value");
GetClient(0)->AwaitMutualSyncCycleCompletion(GetClient(1));
EXPECT_THAT(GetPrefs(0)->GetString(pref_name), Eq("priority value"));
EXPECT_THAT(GetPrefs(1)->GetString(pref_name), Eq(""));
ChangeStringPref(1, pref_name, "non-priority value");
GetClient(1)->AwaitMutualSyncCycleCompletion(GetClient(0));
EXPECT_THAT(GetPrefs(0)->GetString(pref_name), Eq("priority value"));
EXPECT_THAT(GetPrefs(1)->GetString(pref_name), Eq("non-priority value"));
}
} // namespace