blob: 69426a86dfd5a4f743be361703b0bb149becc2c2 [file] [log] [blame]
[email protected]f484f8d52014-06-12 08:38:181// Copyright 2014 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "chrome/browser/extensions/extension_service_test_base.h"
6
dcheng1fc00f12015-12-26 22:18:037#include <utility>
8
[email protected]f484f8d52014-06-12 08:38:189#include "base/command_line.h"
thestig18dfb7a52014-08-26 10:44:0410#include "base/files/file_util.h"
[email protected]f484f8d52014-06-12 08:38:1811#include "base/memory/ref_counted.h"
[email protected]f484f8d52014-06-12 08:38:1812#include "base/path_service.h"
treib9afc6212015-10-30 18:49:5813#include "base/strings/string_number_conversions.h"
14#include "base/strings/stringprintf.h"
gabb15e19072016-05-11 20:45:4115#include "base/threading/thread_task_runner_handle.h"
avia2f4804a2015-12-24 23:11:1316#include "build/build_config.h"
jam726de9f2015-06-02 15:36:0617#include "chrome/browser/extensions/component_loader.h"
Jay Civelliea8f3df2018-01-24 05:17:3218#include "chrome/browser/extensions/crx_installer.h"
[email protected]f484f8d52014-06-12 08:38:1819#include "chrome/browser/extensions/extension_garbage_collector_factory.h"
20#include "chrome/browser/extensions/extension_service.h"
Devlin Cronin9722a722017-12-16 03:35:1021#include "chrome/browser/extensions/load_error_reporter.h"
xiyuanf6a4c6a62016-04-19 18:14:5422#include "chrome/browser/extensions/shared_module_service.h"
[email protected]f484f8d52014-06-12 08:38:1823#include "chrome/browser/extensions/test_extension_system.h"
24#include "chrome/browser/extensions/updater/extension_updater.h"
25#include "chrome/browser/prefs/browser_prefs.h"
[email protected]f484f8d52014-06-12 08:38:1826#include "chrome/common/chrome_constants.h"
27#include "chrome/common/chrome_paths.h"
anthonyvd404d6102015-02-28 00:04:2328#include "chrome/test/base/testing_browser_process.h"
[email protected]f484f8d52014-06-12 08:38:1829#include "chrome/test/base/testing_profile.h"
30#include "components/pref_registry/pref_registry_syncable.h"
maxbogueea16ff412016-10-28 16:35:2931#include "components/sync_preferences/pref_service_mock_factory.h"
32#include "components/sync_preferences/pref_service_syncable.h"
[email protected]f484f8d52014-06-12 08:38:1833#include "content/public/browser/browser_context.h"
Jay Civelliea8f3df2018-01-24 05:17:3234#include "content/public/common/service_manager_connection.h"
[email protected]f484f8d52014-06-12 08:38:1835#include "extensions/browser/extension_prefs.h"
36#include "extensions/browser/extension_registry.h"
Arkadiusz Mlynarczykc4474d72018-01-11 14:45:5637#include "extensions/browser/pref_names.h"
[email protected]f484f8d52014-06-12 08:38:1838
39#if defined(OS_CHROMEOS)
40#include "chrome/browser/chromeos/extensions/install_limiter.h"
41#endif
42
43namespace extensions {
44
45namespace {
46
rdevlin.cronin529ad1a92015-02-26 21:27:3047// By default, we run on the IO loop.
48const int kThreadOptions = content::TestBrowserThreadBundle::IO_MAINLOOP;
49
[email protected]f484f8d52014-06-12 08:38:1850// Create a testing profile according to |params|.
dchengc963c7142016-04-08 03:55:2251std::unique_ptr<TestingProfile> BuildTestingProfile(
[email protected]f484f8d52014-06-12 08:38:1852 const ExtensionServiceTestBase::ExtensionServiceInitParams& params) {
53 TestingProfile::Builder profile_builder;
54 // Create a PrefService that only contains user defined preference values.
maxbogueea16ff412016-10-28 16:35:2955 sync_preferences::PrefServiceMockFactory factory;
[email protected]f484f8d52014-06-12 08:38:1856 // If pref_file is empty, TestingProfile automatically creates
maxbogueea16ff412016-10-28 16:35:2957 // sync_preferences::TestingPrefServiceSyncable instance.
[email protected]f484f8d52014-06-12 08:38:1858 if (!params.pref_file.empty()) {
59 factory.SetUserPrefsFile(params.pref_file,
pranay.kumar07300782015-05-04 14:03:5860 base::ThreadTaskRunnerHandle::Get().get());
[email protected]f484f8d52014-06-12 08:38:1861 scoped_refptr<user_prefs::PrefRegistrySyncable> registry(
62 new user_prefs::PrefRegistrySyncable);
maxbogueea16ff412016-10-28 16:35:2963 std::unique_ptr<sync_preferences::PrefServiceSyncable> prefs(
[email protected]f484f8d52014-06-12 08:38:1864 factory.CreateSyncable(registry.get()));
cm.sanchi549eff32017-11-21 05:58:5665 RegisterUserProfilePrefs(registry.get());
dcheng1fc00f12015-12-26 22:18:0366 profile_builder.SetPrefService(std::move(prefs));
[email protected]f484f8d52014-06-12 08:38:1867 }
68
[email protected]d20d0432014-06-12 17:14:0569 if (params.profile_is_supervised)
70 profile_builder.SetSupervisedUserId("asdf");
[email protected]f484f8d52014-06-12 08:38:1871
72 profile_builder.SetPath(params.profile_path);
73 return profile_builder.Build();
74}
75
76} // namespace
77
78ExtensionServiceTestBase::ExtensionServiceInitParams::
rdevlin.cronin7217be52017-03-24 20:47:0579 ExtensionServiceInitParams() {}
[email protected]f484f8d52014-06-12 08:38:1880
vmpstrb8aacbe2016-02-26 02:00:4881ExtensionServiceTestBase::ExtensionServiceInitParams::
82 ExtensionServiceInitParams(const ExtensionServiceInitParams& other) =
83 default;
84
[email protected]f484f8d52014-06-12 08:38:1885ExtensionServiceTestBase::ExtensionServiceTestBase()
danakjaee67172017-06-13 16:37:0286 : thread_bundle_(kThreadOptions),
87 service_(nullptr),
anthonyvd404d6102015-02-28 00:04:2388 testing_local_state_(TestingBrowserProcess::GetGlobal()),
danakjaee67172017-06-13 16:37:0289 registry_(nullptr) {
[email protected]f484f8d52014-06-12 08:38:1890 base::FilePath test_data_dir;
91 if (!PathService::Get(chrome::DIR_TEST_DATA, &test_data_dir)) {
92 ADD_FAILURE();
93 return;
94 }
95 data_dir_ = test_data_dir.AppendASCII("extensions");
Jay Civelliea8f3df2018-01-24 05:17:3296 CrxInstaller::set_connector_for_test(test_data_decoder_service_.connector());
[email protected]f484f8d52014-06-12 08:38:1897}
98
99ExtensionServiceTestBase::~ExtensionServiceTestBase() {
100 // Why? Because |profile_| has to be destroyed before |at_exit_manager_|, but
101 // is declared above it in the class definition since it's protected.
102 profile_.reset();
103}
104
105ExtensionServiceTestBase::ExtensionServiceInitParams
106ExtensionServiceTestBase::CreateDefaultInitParams() {
107 ExtensionServiceInitParams params;
108 EXPECT_TRUE(temp_dir_.CreateUniqueTempDir());
vabr9142fe22016-09-08 13:19:22109 base::FilePath path = temp_dir_.GetPath();
[email protected]f484f8d52014-06-12 08:38:18110 path = path.Append(FILE_PATH_LITERAL("TestingExtensionsPath"));
111 EXPECT_TRUE(base::DeleteFile(path, true));
112 base::File::Error error = base::File::FILE_OK;
113 EXPECT_TRUE(base::CreateDirectoryAndGetError(path, &error)) << error;
114 base::FilePath prefs_filename =
115 path.Append(FILE_PATH_LITERAL("TestPreferences"));
116 base::FilePath extensions_install_dir =
117 path.Append(FILE_PATH_LITERAL("Extensions"));
118 EXPECT_TRUE(base::DeleteFile(extensions_install_dir, true));
119 EXPECT_TRUE(base::CreateDirectoryAndGetError(extensions_install_dir, &error))
120 << error;
121
122 params.profile_path = path;
123 params.pref_file = prefs_filename;
124 params.extensions_install_dir = extensions_install_dir;
125 return params;
126}
127
128void ExtensionServiceTestBase::InitializeExtensionService(
129 const ExtensionServiceTestBase::ExtensionServiceInitParams& params) {
130 profile_ = BuildTestingProfile(params);
131 CreateExtensionService(params);
132
133 extensions_install_dir_ = params.extensions_install_dir;
134 registry_ = ExtensionRegistry::Get(profile_.get());
135
136 // Garbage collector is typically NULL during tests, so give it a build.
137 ExtensionGarbageCollectorFactory::GetInstance()->SetTestingFactoryAndUse(
138 profile_.get(), &ExtensionGarbageCollectorFactory::BuildInstanceFor);
139}
140
141void ExtensionServiceTestBase::InitializeEmptyExtensionService() {
142 InitializeExtensionService(CreateDefaultInitParams());
143}
144
145void ExtensionServiceTestBase::InitializeInstalledExtensionService(
146 const base::FilePath& prefs_file,
147 const base::FilePath& source_install_dir) {
148 ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
vabr9142fe22016-09-08 13:19:22149 base::FilePath path = temp_dir_.GetPath();
[email protected]f484f8d52014-06-12 08:38:18150
151 path = path.Append(FILE_PATH_LITERAL("TestingExtensionsPath"));
152 ASSERT_TRUE(base::DeleteFile(path, true));
153
154 base::File::Error error = base::File::FILE_OK;
155 ASSERT_TRUE(base::CreateDirectoryAndGetError(path, &error)) << error;
156
157 base::FilePath temp_prefs = path.Append(chrome::kPreferencesFilename);
158 ASSERT_TRUE(base::CopyFile(prefs_file, temp_prefs));
159
160 base::FilePath extensions_install_dir =
161 path.Append(FILE_PATH_LITERAL("Extensions"));
162 ASSERT_TRUE(base::DeleteFile(extensions_install_dir, true));
163 ASSERT_TRUE(
164 base::CopyDirectory(source_install_dir, extensions_install_dir, true));
165
166 ExtensionServiceInitParams params;
167 params.profile_path = path;
168 params.pref_file = temp_prefs;
169 params.extensions_install_dir = extensions_install_dir;
170 InitializeExtensionService(params);
171}
172
173void ExtensionServiceTestBase::InitializeGoodInstalledExtensionService() {
174 base::FilePath source_install_dir =
175 data_dir_.AppendASCII("good").AppendASCII("Extensions");
176 base::FilePath pref_path =
177 source_install_dir.DirName().Append(chrome::kPreferencesFilename);
178 InitializeInstalledExtensionService(pref_path, source_install_dir);
179}
180
181void ExtensionServiceTestBase::InitializeExtensionServiceWithUpdater() {
182 ExtensionServiceInitParams params = CreateDefaultInitParams();
183 params.autoupdate_enabled = true;
184 InitializeExtensionService(params);
185 service_->updater()->Start();
[email protected]f484f8d52014-06-12 08:38:18186}
187
rdevlin.cronin7217be52017-03-24 20:47:05188void ExtensionServiceTestBase::
189 InitializeExtensionServiceWithExtensionsDisabled() {
190 ExtensionServiceInitParams params = CreateDefaultInitParams();
191 params.extensions_enabled = false;
192 InitializeExtensionService(params);
193}
194
treib9afc6212015-10-30 18:49:58195size_t ExtensionServiceTestBase::GetPrefKeyCount() {
196 const base::DictionaryValue* dict =
Arkadiusz Mlynarczykc4474d72018-01-11 14:45:56197 profile()->GetPrefs()->GetDictionary(pref_names::kExtensions);
treib9afc6212015-10-30 18:49:58198 if (!dict) {
199 ADD_FAILURE();
200 return 0;
201 }
202 return dict->size();
203}
204
205void ExtensionServiceTestBase::ValidatePrefKeyCount(size_t count) {
206 EXPECT_EQ(count, GetPrefKeyCount());
207}
208
209testing::AssertionResult ExtensionServiceTestBase::ValidateBooleanPref(
210 const std::string& extension_id,
211 const std::string& pref_path,
212 bool expected_val) {
213 std::string msg = base::StringPrintf("while checking: %s %s == %s",
214 extension_id.c_str(), pref_path.c_str(),
215 expected_val ? "true" : "false");
216
217 PrefService* prefs = profile()->GetPrefs();
218 const base::DictionaryValue* dict =
Arkadiusz Mlynarczykc4474d72018-01-11 14:45:56219 prefs->GetDictionary(pref_names::kExtensions);
treib9afc6212015-10-30 18:49:58220 if (!dict) {
221 return testing::AssertionFailure()
222 << "extension.settings does not exist " << msg;
223 }
224
225 const base::DictionaryValue* pref = NULL;
226 if (!dict->GetDictionary(extension_id, &pref)) {
227 return testing::AssertionFailure()
228 << "extension pref does not exist " << msg;
229 }
230
231 bool val = false;
232 if (!pref->GetBoolean(pref_path, &val)) {
233 return testing::AssertionFailure()
234 << pref_path << " pref not found " << msg;
235 }
236
237 return expected_val == val
238 ? testing::AssertionSuccess()
239 : testing::AssertionFailure() << "base::Value is incorrect " << msg;
240}
241
242void ExtensionServiceTestBase::ValidateIntegerPref(
243 const std::string& extension_id,
244 const std::string& pref_path,
245 int expected_val) {
246 std::string msg = base::StringPrintf("while checking: %s %s == %s",
247 extension_id.c_str(), pref_path.c_str(),
248 base::IntToString(expected_val).c_str());
249
250 PrefService* prefs = profile()->GetPrefs();
251 const base::DictionaryValue* dict =
Arkadiusz Mlynarczykc4474d72018-01-11 14:45:56252 prefs->GetDictionary(pref_names::kExtensions);
treib9afc6212015-10-30 18:49:58253 ASSERT_TRUE(dict != NULL) << msg;
254 const base::DictionaryValue* pref = NULL;
255 ASSERT_TRUE(dict->GetDictionary(extension_id, &pref)) << msg;
256 EXPECT_TRUE(pref != NULL) << msg;
257 int val;
258 ASSERT_TRUE(pref->GetInteger(pref_path, &val)) << msg;
259 EXPECT_EQ(expected_val, val) << msg;
260}
261
262void ExtensionServiceTestBase::ValidateStringPref(
263 const std::string& extension_id,
264 const std::string& pref_path,
265 const std::string& expected_val) {
266 std::string msg = base::StringPrintf("while checking: %s.manifest.%s == %s",
267 extension_id.c_str(), pref_path.c_str(),
268 expected_val.c_str());
269
270 const base::DictionaryValue* dict =
Arkadiusz Mlynarczykc4474d72018-01-11 14:45:56271 profile()->GetPrefs()->GetDictionary(pref_names::kExtensions);
treib9afc6212015-10-30 18:49:58272 ASSERT_TRUE(dict != NULL) << msg;
273 const base::DictionaryValue* pref = NULL;
274 std::string manifest_path = extension_id + ".manifest";
275 ASSERT_TRUE(dict->GetDictionary(manifest_path, &pref)) << msg;
276 EXPECT_TRUE(pref != NULL) << msg;
277 std::string val;
278 ASSERT_TRUE(pref->GetString(pref_path, &val)) << msg;
279 EXPECT_EQ(expected_val, val) << msg;
280}
281
[email protected]f484f8d52014-06-12 08:38:18282void ExtensionServiceTestBase::SetUp() {
Devlin Cronin9722a722017-12-16 03:35:10283 LoadErrorReporter::GetInstance()->ClearErrors();
[email protected]f484f8d52014-06-12 08:38:18284}
285
286void ExtensionServiceTestBase::SetUpTestCase() {
287 // Safe to call multiple times.
Devlin Cronin9722a722017-12-16 03:35:10288 LoadErrorReporter::Init(false); // no noisy errors.
[email protected]f484f8d52014-06-12 08:38:18289}
290
291// These are declared in the .cc so that all inheritors don't need to know
292// that TestingProfile derives Profile derives BrowserContext.
293content::BrowserContext* ExtensionServiceTestBase::browser_context() {
294 return profile_.get();
295}
296
297Profile* ExtensionServiceTestBase::profile() {
298 return profile_.get();
299}
300
pmarko6e36b4632016-12-13 17:45:50301sync_preferences::TestingPrefServiceSyncable*
302ExtensionServiceTestBase::testing_pref_service() {
303 return profile_->GetTestingPrefService();
304}
305
[email protected]f484f8d52014-06-12 08:38:18306void ExtensionServiceTestBase::CreateExtensionService(
307 const ExtensionServiceInitParams& params) {
308 TestExtensionSystem* system =
309 static_cast<TestExtensionSystem*>(ExtensionSystem::Get(profile_.get()));
juncaicf523332015-06-04 00:14:04310 if (!params.is_first_run)
311 ExtensionPrefs::Get(profile_.get())->SetAlertSystemFirstRun();
[email protected]f484f8d52014-06-12 08:38:18312
rdevlin.cronin7217be52017-03-24 20:47:05313 service_ = system->CreateExtensionService(
314 base::CommandLine::ForCurrentProcess(), params.extensions_install_dir,
315 params.autoupdate_enabled, params.extensions_enabled);
[email protected]f484f8d52014-06-12 08:38:18316
jam726de9f2015-06-02 15:36:06317 service_->component_loader()->set_ignore_whitelist_for_testing(true);
[email protected]f484f8d52014-06-12 08:38:18318
319 // When we start up, we want to make sure there is no external provider,
320 // since the ExtensionService on Windows will use the Registry as a default
321 // provider and if there is something already registered there then it will
322 // interfere with the tests. Those tests that need an external provider
323 // will register one specifically.
324 service_->ClearProvidersForTesting();
325
xiyuanf6a4c6a62016-04-19 18:14:54326 service_->RegisterInstallGate(ExtensionPrefs::DELAY_REASON_WAIT_FOR_IMPORTS,
327 service_->shared_module_service());
328
[email protected]f484f8d52014-06-12 08:38:18329#if defined(OS_CHROMEOS)
330 InstallLimiter::Get(profile_.get())->DisableForTest();
331#endif
332}
333
334} // namespace extensions