| Index: chrome/browser/prefs/profile_pref_store_manager_unittest.cc
|
| diff --git a/chrome/browser/prefs/profile_pref_store_manager_unittest.cc b/chrome/browser/prefs/profile_pref_store_manager_unittest.cc
|
| index 62d22de8fd07e71ff35780716525a3f4323729e5..24651eded6fae6a1b3d4b50d82bb272b70831370 100644
|
| --- a/chrome/browser/prefs/profile_pref_store_manager_unittest.cc
|
| +++ b/chrome/browser/prefs/profile_pref_store_manager_unittest.cc
|
| @@ -10,6 +10,7 @@
|
| #include <utility>
|
| #include <vector>
|
|
|
| +#include "base/callback_helpers.h"
|
| #include "base/compiler_specific.h"
|
| #include "base/files/file_enumerator.h"
|
| #include "base/files/file_util.h"
|
| @@ -19,7 +20,11 @@
|
| #include "base/memory/ref_counted.h"
|
| #include "base/run_loop.h"
|
| #include "base/strings/string_util.h"
|
| +#include "base/test/scoped_feature_list.h"
|
| +#include "base/test/sequenced_worker_pool_owner.h"
|
| +#include "base/threading/sequenced_worker_pool.h"
|
| #include "base/values.h"
|
| +#include "chrome/common/chrome_features.h"
|
| #include "components/pref_registry/pref_registry_syncable.h"
|
| #include "components/prefs/json_pref_store.h"
|
| #include "components/prefs/persistent_pref_store.h"
|
| @@ -30,6 +35,11 @@
|
| #include "components/user_prefs/tracked/mock_validation_delegate.h"
|
| #include "components/user_prefs/tracked/pref_hash_filter.h"
|
| #include "components/user_prefs/tracked/pref_names.h"
|
| +#include "content/public/common/service_names.mojom.h"
|
| +#include "services/preferences/public/cpp/pref_service_main.h"
|
| +#include "services/preferences/public/interfaces/preferences.mojom.h"
|
| +#include "services/service_manager/public/cpp/connector.h"
|
| +#include "services/service_manager/public/cpp/service_context.h"
|
| #include "testing/gtest/include/gtest/gtest.h"
|
|
|
| namespace {
|
| @@ -68,6 +78,39 @@ class RegistryVerifier : public PrefStore::Observer {
|
| scoped_refptr<PrefRegistry> pref_registry_;
|
| };
|
|
|
| +class PrefStoreReadObserver : public PrefStore::Observer {
|
| + public:
|
| + explicit PrefStoreReadObserver(scoped_refptr<PersistentPrefStore> pref_store)
|
| + : pref_store_(std::move(pref_store)) {
|
| + pref_store_->AddObserver(this);
|
| + }
|
| +
|
| + ~PrefStoreReadObserver() override { pref_store_->RemoveObserver(this); }
|
| +
|
| + PersistentPrefStore::PrefReadError Read() {
|
| + base::RunLoop run_loop;
|
| + stop_waiting_ = run_loop.QuitClosure();
|
| + pref_store_->ReadPrefsAsync(nullptr);
|
| + run_loop.Run();
|
| + return pref_store_->GetReadError();
|
| + }
|
| +
|
| + // PrefStore::Observer implementation
|
| + void OnPrefValueChanged(const std::string& key) override {}
|
| +
|
| + void OnInitializationCompleted(bool succeeded) override {
|
| + if (!stop_waiting_.is_null()) {
|
| + base::ResetAndReturn(&stop_waiting_).Run();
|
| + }
|
| + }
|
| +
|
| + private:
|
| + scoped_refptr<PersistentPrefStore> pref_store_;
|
| + base::Closure stop_waiting_;
|
| +
|
| + DISALLOW_COPY_AND_ASSIGN(PrefStoreReadObserver);
|
| +};
|
| +
|
| const char kUnprotectedPref[] = "unprotected_pref";
|
| const char kTrackedAtomic[] = "tracked_atomic";
|
| const char kProtectedAtomic[] = "protected_atomic";
|
| @@ -88,7 +131,7 @@ const size_t kReportingIdCount = 3u;
|
|
|
| } // namespace
|
|
|
| -class ProfilePrefStoreManagerTest : public testing::Test {
|
| +class ProfilePrefStoreManagerTest : public testing::TestWithParam<bool> {
|
| public:
|
| ProfilePrefStoreManagerTest()
|
| : configuration_(kConfiguration,
|
| @@ -99,9 +142,33 @@ class ProfilePrefStoreManagerTest : public testing::Test {
|
| reset_recorded_(false) {}
|
|
|
| void SetUp() override {
|
| + worker_pool_ = base::MakeUnique<base::SequencedWorkerPoolOwner>(
|
| + 2, "ProfilePrefStoreManagerTest");
|
| + if (GetParam()) {
|
| + feature_list_.InitAndEnableFeature(features::kPrefService);
|
| + service_manager::mojom::ServicePtr service_ptr;
|
| + pref_service_context_ = base::MakeUnique<service_manager::ServiceContext>(
|
| + prefs::CreatePrefService(std::set<PrefValueStore::PrefStoreType>(),
|
| + worker_pool_->pool()),
|
| + mojo::MakeRequest(&service_ptr));
|
| + connector_ = service_manager::Connector::Create(&connector_request_);
|
| + service_manager::Connector::TestApi test_api(connector_.get());
|
| + test_api.OverrideBinderForTesting(
|
| + prefs::mojom::kPrefStoreServiceName,
|
| + prefs::mojom::PrefStoreConnector::Name_,
|
| + base::Bind(&ProfilePrefStoreManagerTest::BindInterface,
|
| + base::Unretained(this),
|
| + prefs::mojom::PrefStoreConnector::Name_));
|
| + test_api.OverrideBinderForTesting(
|
| + prefs::mojom::kPrefStoreServiceName,
|
| + prefs::mojom::PrefServiceControl::Name_,
|
| + base::Bind(&ProfilePrefStoreManagerTest::BindInterface,
|
| + base::Unretained(this),
|
| + prefs::mojom::PrefServiceControl::Name_));
|
| + } else {
|
| + feature_list_.InitAndDisableFeature(features::kPrefService);
|
| + }
|
| mock_validation_delegate_record_ = new MockValidationDelegateRecord;
|
| - mock_validation_delegate_ = base::MakeUnique<MockValidationDelegate>(
|
| - mock_validation_delegate_record_);
|
| ProfilePrefStoreManager::RegisterProfilePrefs(profile_pref_registry_.get());
|
| for (const PrefHashFilter::TrackedPreferenceMetadata* it = kConfiguration;
|
| it != kConfiguration + arraysize(kConfiguration);
|
| @@ -131,14 +198,38 @@ class ProfilePrefStoreManagerTest : public testing::Test {
|
| }
|
|
|
| void ReloadConfiguration() {
|
| + RelaunchPrefService();
|
| manager_.reset(new ProfilePrefStoreManager(
|
| profile_dir_.GetPath(), configuration_, kReportingIdCount, seed_,
|
| "device_id", &local_state_));
|
| }
|
|
|
| - void TearDown() override { DestroyPrefStore(); }
|
| + void TearDown() override {
|
| + DestroyPrefStore();
|
| + if (GetParam()) {
|
| + connector_.reset();
|
| + pref_service_context_.reset();
|
| + }
|
| + worker_pool_.reset();
|
| + }
|
|
|
| protected:
|
| + bool SupportsPreferenceTracking() {
|
| + return ProfilePrefStoreManager::kPlatformSupportsPreferenceTracking &&
|
| + !GetParam();
|
| + }
|
| +
|
| + void RelaunchPrefService() {
|
| + if (!GetParam())
|
| + return;
|
| +
|
| + service_manager::mojom::ServicePtr service_ptr;
|
| + pref_service_context_ = base::MakeUnique<service_manager::ServiceContext>(
|
| + prefs::CreatePrefService(std::set<PrefValueStore::PrefStoreType>(),
|
| + worker_pool_->pool()),
|
| + mojo::MakeRequest(&service_ptr));
|
| + }
|
| +
|
| // Verifies whether a reset was reported via the RecordReset() hook. Also
|
| // verifies that GetResetTime() was set (or not) accordingly.
|
| void VerifyResetRecorded(bool reset_expected) {
|
| @@ -170,12 +261,15 @@ class ProfilePrefStoreManagerTest : public testing::Test {
|
| void InitializePrefs() {
|
| // According to the implementation of ProfilePrefStoreManager, this is
|
| // actually a SegregatedPrefStore backed by two underlying pref stores.
|
| + mock_validation_delegate_ = base::MakeUnique<MockValidationDelegate>(
|
| + mock_validation_delegate_record_);
|
| scoped_refptr<PersistentPrefStore> pref_store =
|
| manager_->CreateProfilePrefStore(
|
| main_message_loop_.task_runner(),
|
| base::Bind(&ProfilePrefStoreManagerTest::RecordReset,
|
| base::Unretained(this)),
|
| - mock_validation_delegate_.get());
|
| + mock_validation_delegate_.get(), connector_.get(),
|
| + profile_pref_registry_);
|
| InitializePrefStore(pref_store.get());
|
| pref_store = NULL;
|
| base::RunLoop().RunUntilIdle();
|
| @@ -188,6 +282,12 @@ class ProfilePrefStoreManagerTest : public testing::Test {
|
| // while our RegistryVerifier is watching.
|
| pref_store_->CommitPendingWrite();
|
| base::RunLoop().RunUntilIdle();
|
| + base::RunLoop run_loop;
|
| + JsonPrefStore::GetTaskRunnerForFile(profile_dir_.GetPath(),
|
| + worker_pool_->pool().get())
|
| + ->PostTaskAndReply(FROM_HERE, base::Bind(&base::DoNothing),
|
| + run_loop.QuitClosure());
|
| + run_loop.Run();
|
|
|
| pref_store_->RemoveObserver(®istry_verifier_);
|
| pref_store_ = NULL;
|
| @@ -195,11 +295,13 @@ class ProfilePrefStoreManagerTest : public testing::Test {
|
| // case...
|
| base::RunLoop().RunUntilIdle();
|
| }
|
| + RelaunchPrefService();
|
| }
|
|
|
| void InitializePrefStore(PersistentPrefStore* pref_store) {
|
| pref_store->AddObserver(®istry_verifier_);
|
| - PersistentPrefStore::PrefReadError error = pref_store->ReadPrefs();
|
| + PrefStoreReadObserver read_observer(pref_store);
|
| + PersistentPrefStore::PrefReadError error = read_observer.Read();
|
| EXPECT_EQ(PersistentPrefStore::PREF_READ_ERROR_NO_FILE, error);
|
| pref_store->SetValue(kTrackedAtomic, base::MakeUnique<base::Value>(kFoobar),
|
| WriteablePrefStore::DEFAULT_PREF_WRITE_FLAGS);
|
| @@ -212,17 +314,28 @@ class ProfilePrefStoreManagerTest : public testing::Test {
|
| pref_store->RemoveObserver(®istry_verifier_);
|
| pref_store->CommitPendingWrite();
|
| base::RunLoop().RunUntilIdle();
|
| + base::RunLoop run_loop;
|
| + JsonPrefStore::GetTaskRunnerForFile(profile_dir_.GetPath(),
|
| + worker_pool_->pool().get())
|
| + ->PostTaskAndReply(FROM_HERE, base::Bind(&base::DoNothing),
|
| + run_loop.QuitClosure());
|
| + run_loop.Run();
|
| }
|
|
|
| void LoadExistingPrefs() {
|
| DestroyPrefStore();
|
| + mock_validation_delegate_ = base::MakeUnique<MockValidationDelegate>(
|
| + mock_validation_delegate_record_);
|
| pref_store_ = manager_->CreateProfilePrefStore(
|
| - main_message_loop_.task_runner(),
|
| + JsonPrefStore::GetTaskRunnerForFile(profile_dir_.GetPath(),
|
| + worker_pool_->pool().get()),
|
| base::Bind(&ProfilePrefStoreManagerTest::RecordReset,
|
| base::Unretained(this)),
|
| - NULL);
|
| + mock_validation_delegate_.get(), connector_.get(),
|
| + profile_pref_registry_);
|
| pref_store_->AddObserver(®istry_verifier_);
|
| - pref_store_->ReadPrefs();
|
| + PrefStoreReadObserver read_observer(pref_store_);
|
| + read_observer.Read();
|
| }
|
|
|
| void ReplaceStringInPrefs(const std::string& find,
|
| @@ -256,7 +369,7 @@ class ProfilePrefStoreManagerTest : public testing::Test {
|
|
|
| void ExpectValidationObserved(const std::string& pref_path) {
|
| // No validations are expected for platforms that do not support tracking.
|
| - if (!ProfilePrefStoreManager::kPlatformSupportsPreferenceTracking)
|
| + if (!SupportsPreferenceTracking())
|
| return;
|
| if (!mock_validation_delegate_record_->GetEventForPath(pref_path))
|
| ADD_FAILURE() << "No validation observed for preference: " << pref_path;
|
| @@ -269,7 +382,8 @@ class ProfilePrefStoreManagerTest : public testing::Test {
|
| scoped_refptr<user_prefs::PrefRegistrySyncable> profile_pref_registry_;
|
| RegistryVerifier registry_verifier_;
|
| scoped_refptr<MockValidationDelegateRecord> mock_validation_delegate_record_;
|
| - std::unique_ptr<MockValidationDelegate> mock_validation_delegate_;
|
| + std::unique_ptr<prefs::mojom::TrackedPreferenceValidationDelegate>
|
| + mock_validation_delegate_;
|
| std::unique_ptr<ProfilePrefStoreManager> manager_;
|
| scoped_refptr<PersistentPrefStore> pref_store_;
|
|
|
| @@ -284,10 +398,26 @@ class ProfilePrefStoreManagerTest : public testing::Test {
|
| reset_recorded_ = true;
|
| }
|
|
|
| + void BindInterface(const std::string& interface_name,
|
| + mojo::ScopedMessagePipeHandle handle) {
|
| + service_manager::ServiceInfo source(
|
| + service_manager::Identity(content::mojom::kBrowserServiceName,
|
| + service_manager::mojom::kRootUserID),
|
| + service_manager::InterfaceProviderSpecMap());
|
| + static_cast<service_manager::mojom::Service*>(pref_service_context_.get())
|
| + ->OnBindInterface(source, interface_name, std::move(handle),
|
| + base::Bind(&base::DoNothing));
|
| + }
|
| +
|
| + base::test::ScopedFeatureList feature_list_;
|
| bool reset_recorded_;
|
| + std::unique_ptr<base::SequencedWorkerPoolOwner> worker_pool_;
|
| + std::unique_ptr<service_manager::ServiceContext> pref_service_context_;
|
| + std::unique_ptr<service_manager::Connector> connector_;
|
| + service_manager::mojom::ConnectorRequest connector_request_;
|
| };
|
|
|
| -TEST_F(ProfilePrefStoreManagerTest, StoreValues) {
|
| +TEST_P(ProfilePrefStoreManagerTest, StoreValues) {
|
| InitializePrefs();
|
|
|
| LoadExistingPrefs();
|
| @@ -299,7 +429,7 @@ TEST_F(ProfilePrefStoreManagerTest, StoreValues) {
|
| ExpectValidationObserved(kProtectedAtomic);
|
| }
|
|
|
| -TEST_F(ProfilePrefStoreManagerTest, ProtectValues) {
|
| +TEST_P(ProfilePrefStoreManagerTest, ProtectValues) {
|
| InitializePrefs();
|
|
|
| ReplaceStringInPrefs(kFoobar, kBarfoo);
|
| @@ -313,16 +443,15 @@ TEST_F(ProfilePrefStoreManagerTest, ProtectValues) {
|
|
|
| // If preference tracking is supported, the tampered value of kProtectedAtomic
|
| // will be discarded at load time, leaving this preference undefined.
|
| - EXPECT_NE(ProfilePrefStoreManager::kPlatformSupportsPreferenceTracking,
|
| + EXPECT_NE(SupportsPreferenceTracking(),
|
| pref_store_->GetValue(kProtectedAtomic, NULL));
|
| - VerifyResetRecorded(
|
| - ProfilePrefStoreManager::kPlatformSupportsPreferenceTracking);
|
| + VerifyResetRecorded(SupportsPreferenceTracking());
|
|
|
| ExpectValidationObserved(kTrackedAtomic);
|
| ExpectValidationObserved(kProtectedAtomic);
|
| }
|
|
|
| -TEST_F(ProfilePrefStoreManagerTest, InitializePrefsFromMasterPrefs) {
|
| +TEST_P(ProfilePrefStoreManagerTest, InitializePrefsFromMasterPrefs) {
|
| auto master_prefs = base::MakeUnique<base::DictionaryValue>();
|
| master_prefs->Set(kTrackedAtomic, new base::Value(kFoobar));
|
| master_prefs->Set(kProtectedAtomic, new base::Value(kHelloWorld));
|
| @@ -338,7 +467,7 @@ TEST_F(ProfilePrefStoreManagerTest, InitializePrefsFromMasterPrefs) {
|
| VerifyResetRecorded(false);
|
| }
|
|
|
| -TEST_F(ProfilePrefStoreManagerTest, UnprotectedToProtected) {
|
| +TEST_P(ProfilePrefStoreManagerTest, UnprotectedToProtected) {
|
| InitializePrefs();
|
|
|
| ExpectValidationObserved(kTrackedAtomic);
|
| @@ -379,13 +508,12 @@ TEST_F(ProfilePrefStoreManagerTest, UnprotectedToProtected) {
|
| // lead to a reset.
|
| ReplaceStringInPrefs(kBarfoo, kFoobar);
|
| LoadExistingPrefs();
|
| - EXPECT_NE(ProfilePrefStoreManager::kPlatformSupportsPreferenceTracking,
|
| + EXPECT_NE(SupportsPreferenceTracking(),
|
| pref_store_->GetValue(kUnprotectedPref, NULL));
|
| - VerifyResetRecorded(
|
| - ProfilePrefStoreManager::kPlatformSupportsPreferenceTracking);
|
| + VerifyResetRecorded(SupportsPreferenceTracking());
|
| }
|
|
|
| -TEST_F(ProfilePrefStoreManagerTest, NewPrefWhenFirstProtecting) {
|
| +TEST_P(ProfilePrefStoreManagerTest, NewPrefWhenFirstProtecting) {
|
| std::vector<PrefHashFilter::TrackedPreferenceMetadata>
|
| original_configuration = configuration_;
|
| for (std::vector<PrefHashFilter::TrackedPreferenceMetadata>::iterator it =
|
| @@ -425,7 +553,7 @@ TEST_F(ProfilePrefStoreManagerTest, NewPrefWhenFirstProtecting) {
|
| VerifyResetRecorded(false);
|
| }
|
|
|
| -TEST_F(ProfilePrefStoreManagerTest, UnprotectedToProtectedWithoutTrust) {
|
| +TEST_P(ProfilePrefStoreManagerTest, UnprotectedToProtectedWithoutTrust) {
|
| InitializePrefs();
|
|
|
| ExpectValidationObserved(kTrackedAtomic);
|
| @@ -445,15 +573,14 @@ TEST_F(ProfilePrefStoreManagerTest, UnprotectedToProtectedWithoutTrust) {
|
|
|
| // If preference tracking is supported, kUnprotectedPref will have been
|
| // discarded because new values are not accepted without a valid super MAC.
|
| - EXPECT_NE(ProfilePrefStoreManager::kPlatformSupportsPreferenceTracking,
|
| + EXPECT_NE(SupportsPreferenceTracking(),
|
| pref_store_->GetValue(kUnprotectedPref, NULL));
|
| - VerifyResetRecorded(
|
| - ProfilePrefStoreManager::kPlatformSupportsPreferenceTracking);
|
| + VerifyResetRecorded(SupportsPreferenceTracking());
|
| }
|
|
|
| // This test verifies that preference values are correctly maintained when a
|
| // preference's protection state changes from protected to unprotected.
|
| -TEST_F(ProfilePrefStoreManagerTest, ProtectedToUnprotected) {
|
| +TEST_P(ProfilePrefStoreManagerTest, ProtectedToUnprotected) {
|
| InitializePrefs();
|
|
|
| ExpectValidationObserved(kTrackedAtomic);
|
| @@ -495,3 +622,7 @@ TEST_F(ProfilePrefStoreManagerTest, ProtectedToUnprotected) {
|
| ExpectStringValueEquals(kProtectedAtomic, kGoodbyeWorld);
|
| VerifyResetRecorded(false);
|
| }
|
| +
|
| +INSTANTIATE_TEST_CASE_P(ProfilePrefStoreManagerTest,
|
| + ProfilePrefStoreManagerTest,
|
| + testing::Bool());
|
|
|