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()); |