1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279
|
// Copyright 2014 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef CHROME_BROWSER_EXTENSIONS_EXTENSION_SERVICE_TEST_BASE_H_
#define CHROME_BROWSER_EXTENSIONS_EXTENSION_SERVICE_TEST_BASE_H_
#include <stddef.h>
#include <memory>
#include <string>
#include "base/files/file_path.h"
#include "base/files/scoped_temp_dir.h"
#include "base/memory/raw_ptr.h"
#include "base/test/scoped_feature_list.h"
#include "build/build_config.h"
#include "build/chromeos_buildflags.h"
#include "chrome/browser/extensions/scoped_test_mv2_enabler.h"
#include "chrome/common/chrome_constants.h"
#include "chrome/test/base/scoped_testing_local_state.h"
#include "chrome/test/base/testing_profile.h"
#include "components/policy/core/common/mock_configuration_policy_provider.h"
#include "components/policy/core/common/policy_service.h"
#include "content/public/test/browser_task_environment.h"
#include "content/public/test/test_renderer_host.h"
#include "content/public/test/test_utils.h"
#include "extensions/browser/sandboxed_unpacker.h"
#include "extensions/buildflags/buildflags.h"
#include "extensions/common/extension.h"
#include "testing/gtest/include/gtest/gtest.h"
#if BUILDFLAG(IS_CHROMEOS)
#include "chrome/browser/ash/app_mode/kiosk_chrome_app_manager.h"
#include "chrome/browser/ash/settings/scoped_cros_settings_test_helper.h"
#include "components/user_manager/scoped_user_manager.h"
#endif
static_assert(BUILDFLAG(ENABLE_EXTENSIONS_CORE));
class Profile;
class TestingProfile;
namespace content {
class BrowserContext;
class BrowserTaskEnvironment;
} // namespace content
namespace sync_preferences {
class TestingPrefServiceSyncable;
}
namespace extensions {
class ExtensionRegistrar;
class ExtensionRegistry;
class ExtensionService;
// A unittest infrastructure which creates an ExtensionService. Whenever
// possible, use this instead of creating a browsertest.
// Note: Before adding methods to this class, please, please, please think about
// whether they should go here or in a more specific subclass. Lots of things
// need an ExtensionService, but they don't all need to know how you want yours
// to be initialized.
class ExtensionServiceTestBase : public testing::Test {
public:
struct ExtensionServiceInitParams {
// If set, even if it is empty string, creates a pref file in the profile
// directory with the given content, and initializes user prefs store
// referring the file.
// If not, sync_preferences::TestingPrefServiceSyncable is used.
std::optional<std::string> prefs_content;
// If not empty, copies both directories to the profile directory.
base::FilePath extensions_dir;
base::FilePath unpacked_extensions_dir;
bool autoupdate_enabled = false;
bool extensions_enabled = true;
bool is_first_run = true;
bool profile_is_supervised = false;
bool profile_is_guest = false;
bool enable_bookmark_model = false;
bool enable_install_limiter = false;
TestingProfile::TestingFactories testing_factories;
ExtensionServiceInitParams();
ExtensionServiceInitParams(ExtensionServiceInitParams&& other);
ExtensionServiceInitParams& operator=(ExtensionServiceInitParams&& other) =
delete;
ExtensionServiceInitParams(const ExtensionServiceInitParams& other) =
delete;
ExtensionServiceInitParams& operator=(
const ExtensionServiceInitParams& other) = delete;
~ExtensionServiceInitParams();
// Sets the prefs_content to the content in the given file.
[[nodiscard]] bool SetPrefsContentFromFile(const base::FilePath& filepath);
// Configures prefs_content and extensions_dir from the test data directory
// specified by the `filepath`.
// There must be a file named "Preferences" in the test data directory
// containing the prefs content.
// Also, there must be a directory named "Extensions" containing extensions
// data for testing.
[[nodiscard]] bool ConfigureByTestDataDirectory(
const base::FilePath& filepath);
};
ExtensionServiceTestBase(const ExtensionServiceTestBase&) = delete;
ExtensionServiceTestBase& operator=(const ExtensionServiceTestBase&) = delete;
// Public because parameterized test cases need it to be, or else the compiler
// barfs.
static void SetUpTestSuite(); // faux-verride (static override).
protected:
ExtensionServiceTestBase();
// Alternatively, a subclass may pass a BrowserTaskEnvironment directly.
explicit ExtensionServiceTestBase(
std::unique_ptr<content::BrowserTaskEnvironment> task_environment);
~ExtensionServiceTestBase() override;
// testing::Test implementation.
void SetUp() override;
void TearDown() override;
// Nulls out pointers to avoid dangling. May be called multiple times.
void Shutdown();
// Initialize an ExtensionService according to the given `params`.
virtual void InitializeExtensionService(ExtensionServiceInitParams params);
// Whether MV2 extensions should be allowed. Defaults to true.
virtual bool ShouldAllowMV2Extensions();
// Initialize an empty ExtensionService using a production, on-disk pref file.
// See documentation for `prefs_content`.
void InitializeEmptyExtensionService();
// Initialize an ExtensionService with a few already-installed extensions.
void InitializeGoodInstalledExtensionService();
// Initialize an ExtensionService with autoupdate enabled.
void InitializeExtensionServiceWithUpdater();
// Initializes an ExtensionService without extensions enabled.
void InitializeExtensionServiceWithExtensionsDisabled();
// Helpers to check the existence and values of extension prefs.
size_t GetPrefKeyCount();
void ValidatePrefKeyCount(size_t count);
testing::AssertionResult ValidateBooleanPref(const std::string& extension_id,
const std::string& pref_path,
bool expected_val);
void ValidateIntegerPref(const std::string& extension_id,
const std::string& pref_path,
int expected_val);
void ValidateStringPref(const std::string& extension_id,
const std::string& pref_path,
const std::string& expected_val);
// TODO(rdevlin.cronin): Pull out more methods from ExtensionServiceTest that
// are commonly used and/or reimplemented. For instance, methods to install
// extensions from various locations, etc.
content::BrowserContext* browser_context();
Profile* profile();
// Turn on/off the guest session on the main profile.
void SetGuestSessionOnProfile(bool guest_sesion);
sync_preferences::TestingPrefServiceSyncable* testing_pref_service();
ExtensionService* service() { return service_; }
ExtensionRegistrar* registrar() { return registrar_; }
ExtensionRegistry* registry() { return registry_; }
const base::FilePath& extensions_install_dir() const {
return extensions_install_dir_;
}
const base::FilePath& unpacked_install_dir() const {
return unpacked_install_dir_;
}
const base::FilePath& data_dir() const { return data_dir_; }
const base::ScopedTempDir& temp_dir() const { return temp_dir_; }
content::BrowserTaskEnvironment* task_environment() {
return task_environment_.get();
}
policy::MockConfigurationPolicyProvider* policy_provider() {
return &policy_provider_;
}
policy::PolicyService* policy_service() { return policy_service_.get(); }
#if BUILDFLAG(IS_CHROMEOS)
ash::ScopedCrosSettingsTestHelper& cros_settings_test_helper() {
return cros_settings_test_helper_;
}
#endif // BUILDFLAG(IS_CHROMEOS)
private:
// If a test uses a feature list, it should be destroyed after
// `task_environment_`, to avoid tsan data races between the ScopedFeatureList
// destructor, and any tasks running on different threads that check if a
// feature is enabled. ~BrowserTaskEnvironment will make sure those tasks
// finish before `feature_list_` is destroyed.
base::test::ScopedFeatureList feature_list_;
// Must be declared before anything that may make use of the
// directory so as to ensure files are closed before cleanup.
base::ScopedTempDir temp_dir_;
// The MessageLoop is used by RenderViewHostTestEnabler, so this must be
// created before it.
std::unique_ptr<content::BrowserTaskEnvironment> task_environment_;
// Enable creation of WebContents without initializing a renderer.
content::RenderViewHostTestEnabler rvh_test_enabler_;
// Provides policies for the PolicyService below, so this must be created
// before it.
testing::NiceMock<policy::MockConfigurationPolicyProvider> policy_provider_;
// PolicyService for the testing profile, so unit tests can use custom
// policies.
std::unique_ptr<policy::PolicyService> policy_service_;
protected:
// It's unfortunate that these are exposed to subclasses (rather than used
// through the accessor methods above), but too many tests already use them
// directly.
// The associated testing profile.
std::unique_ptr<TestingProfile> profile_;
// The ExtensionService, whose lifetime is managed by `profile`'s
// ExtensionSystem.
raw_ptr<ExtensionService, DanglingUntriaged> service_;
ScopedTestingLocalState testing_local_state_;
private:
void CreateExtensionService(bool is_first_run,
bool autoupdate_enabled,
bool extensions_enabled,
bool enable_install_limiter);
// The directory into which extensions are installed.
base::FilePath extensions_install_dir_;
// The directory into which unpacked extensions are installed.
base::FilePath unpacked_install_dir_;
// chrome/test/data/extensions/
base::FilePath data_dir_;
content::InProcessUtilityThreadHelper in_process_utility_thread_helper_;
// The associated ExtensionRegistry, for convenience.
raw_ptr<extensions::ExtensionRegistry, DanglingUntriaged> registry_;
// The associated ExtensionRegistrar, for convenience.
raw_ptr<ExtensionRegistrar> registrar_ = nullptr;
#if BUILDFLAG(IS_CHROMEOS)
ash::ScopedCrosSettingsTestHelper cros_settings_test_helper_;
std::unique_ptr<ash::KioskChromeAppManager> kiosk_chrome_app_manager_;
user_manager::ScopedUserManager user_manager_;
#endif
// An override that ignores CRX3 publisher signatures.
SandboxedUnpacker::ScopedVerifierFormatOverrideForTest
verifier_format_override_;
// An override that allows MV2 extensions to be loaded.
std::optional<ScopedTestMV2Enabler> mv2_enabler_;
};
} // namespace extensions
#endif // CHROME_BROWSER_EXTENSIONS_EXTENSION_SERVICE_TEST_BASE_H_
|