blob: 1a6dbfc6b59a61ebad1f04f4cf86cf61c7352576 [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
Sylvain Defresne711ff6b2018-10-04 12:33:549#include "base/bind.h"
[email protected]f484f8d52014-06-12 08:38:1810#include "base/command_line.h"
thestig18dfb7a52014-08-26 10:44:0411#include "base/files/file_util.h"
[email protected]f484f8d52014-06-12 08:38:1812#include "base/memory/ref_counted.h"
[email protected]f484f8d52014-06-12 08:38:1813#include "base/path_service.h"
treib9afc6212015-10-30 18:49:5814#include "base/strings/string_number_conversions.h"
15#include "base/strings/stringprintf.h"
gabb15e19072016-05-11 20:45:4116#include "base/threading/thread_task_runner_handle.h"
avia2f4804a2015-12-24 23:11:1317#include "build/build_config.h"
jam726de9f2015-06-02 15:36:0618#include "chrome/browser/extensions/component_loader.h"
Jay Civelliea8f3df2018-01-24 05:17:3219#include "chrome/browser/extensions/crx_installer.h"
[email protected]f484f8d52014-06-12 08:38:1820#include "chrome/browser/extensions/extension_garbage_collector_factory.h"
21#include "chrome/browser/extensions/extension_service.h"
Devlin Cronin9722a722017-12-16 03:35:1022#include "chrome/browser/extensions/load_error_reporter.h"
xiyuanf6a4c6a62016-04-19 18:14:5423#include "chrome/browser/extensions/shared_module_service.h"
[email protected]f484f8d52014-06-12 08:38:1824#include "chrome/browser/extensions/test_extension_system.h"
25#include "chrome/browser/extensions/updater/extension_updater.h"
26#include "chrome/browser/prefs/browser_prefs.h"
[email protected]f484f8d52014-06-12 08:38:1827#include "chrome/common/chrome_constants.h"
28#include "chrome/common/chrome_paths.h"
anthonyvd404d6102015-02-28 00:04:2329#include "chrome/test/base/testing_browser_process.h"
[email protected]f484f8d52014-06-12 08:38:1830#include "chrome/test/base/testing_profile.h"
31#include "components/pref_registry/pref_registry_syncable.h"
maxbogueea16ff412016-10-28 16:35:2932#include "components/sync_preferences/pref_service_mock_factory.h"
33#include "components/sync_preferences/pref_service_syncable.h"
[email protected]f484f8d52014-06-12 08:38:1834#include "content/public/browser/browser_context.h"
Christian Dullweber64d38d082018-02-02 14:06:3135#include "content/public/browser/storage_partition.h"
Jay Civelliea8f3df2018-01-24 05:17:3236#include "content/public/common/service_manager_connection.h"
[email protected]f484f8d52014-06-12 08:38:1837#include "extensions/browser/extension_prefs.h"
38#include "extensions/browser/extension_registry.h"
Arkadiusz Mlynarczykc4474d72018-01-11 14:45:5639#include "extensions/browser/pref_names.h"
[email protected]f484f8d52014-06-12 08:38:1840
41#if defined(OS_CHROMEOS)
42#include "chrome/browser/chromeos/extensions/install_limiter.h"
43#endif
44
45namespace extensions {
46
47namespace {
48
rdevlin.cronin529ad1a92015-02-26 21:27:3049// By default, we run on the IO loop.
50const int kThreadOptions = content::TestBrowserThreadBundle::IO_MAINLOOP;
51
[email protected]f484f8d52014-06-12 08:38:1852// Create a testing profile according to |params|.
dchengc963c7142016-04-08 03:55:2253std::unique_ptr<TestingProfile> BuildTestingProfile(
[email protected]f484f8d52014-06-12 08:38:1854 const ExtensionServiceTestBase::ExtensionServiceInitParams& params) {
55 TestingProfile::Builder profile_builder;
56 // Create a PrefService that only contains user defined preference values.
maxbogueea16ff412016-10-28 16:35:2957 sync_preferences::PrefServiceMockFactory factory;
[email protected]f484f8d52014-06-12 08:38:1858 // If pref_file is empty, TestingProfile automatically creates
maxbogueea16ff412016-10-28 16:35:2959 // sync_preferences::TestingPrefServiceSyncable instance.
[email protected]f484f8d52014-06-12 08:38:1860 if (!params.pref_file.empty()) {
61 factory.SetUserPrefsFile(params.pref_file,
pranay.kumar07300782015-05-04 14:03:5862 base::ThreadTaskRunnerHandle::Get().get());
[email protected]f484f8d52014-06-12 08:38:1863 scoped_refptr<user_prefs::PrefRegistrySyncable> registry(
64 new user_prefs::PrefRegistrySyncable);
maxbogueea16ff412016-10-28 16:35:2965 std::unique_ptr<sync_preferences::PrefServiceSyncable> prefs(
[email protected]f484f8d52014-06-12 08:38:1866 factory.CreateSyncable(registry.get()));
cm.sanchi549eff32017-11-21 05:58:5667 RegisterUserProfilePrefs(registry.get());
dcheng1fc00f12015-12-26 22:18:0368 profile_builder.SetPrefService(std::move(prefs));
[email protected]f484f8d52014-06-12 08:38:1869 }
70
[email protected]d20d0432014-06-12 17:14:0571 if (params.profile_is_supervised)
72 profile_builder.SetSupervisedUserId("asdf");
[email protected]f484f8d52014-06-12 08:38:1873
74 profile_builder.SetPath(params.profile_path);
75 return profile_builder.Build();
76}
77
78} // namespace
79
80ExtensionServiceTestBase::ExtensionServiceInitParams::
rdevlin.cronin7217be52017-03-24 20:47:0581 ExtensionServiceInitParams() {}
[email protected]f484f8d52014-06-12 08:38:1882
vmpstrb8aacbe2016-02-26 02:00:4883ExtensionServiceTestBase::ExtensionServiceInitParams::
84 ExtensionServiceInitParams(const ExtensionServiceInitParams& other) =
85 default;
86
[email protected]f484f8d52014-06-12 08:38:1887ExtensionServiceTestBase::ExtensionServiceTestBase()
danakjaee67172017-06-13 16:37:0288 : thread_bundle_(kThreadOptions),
89 service_(nullptr),
anthonyvd404d6102015-02-28 00:04:2390 testing_local_state_(TestingBrowserProcess::GetGlobal()),
danakjaee67172017-06-13 16:37:0291 registry_(nullptr) {
[email protected]f484f8d52014-06-12 08:38:1892 base::FilePath test_data_dir;
Avi Drissman9098f9002018-05-04 00:11:5293 if (!base::PathService::Get(chrome::DIR_TEST_DATA, &test_data_dir)) {
[email protected]f484f8d52014-06-12 08:38:1894 ADD_FAILURE();
95 return;
96 }
97 data_dir_ = test_data_dir.AppendASCII("extensions");
98}
99
100ExtensionServiceTestBase::~ExtensionServiceTestBase() {
101 // Why? Because |profile_| has to be destroyed before |at_exit_manager_|, but
102 // is declared above it in the class definition since it's protected.
103 profile_.reset();
104}
105
106ExtensionServiceTestBase::ExtensionServiceInitParams
107ExtensionServiceTestBase::CreateDefaultInitParams() {
108 ExtensionServiceInitParams params;
109 EXPECT_TRUE(temp_dir_.CreateUniqueTempDir());
vabr9142fe22016-09-08 13:19:22110 base::FilePath path = temp_dir_.GetPath();
[email protected]f484f8d52014-06-12 08:38:18111 path = path.Append(FILE_PATH_LITERAL("TestingExtensionsPath"));
112 EXPECT_TRUE(base::DeleteFile(path, true));
113 base::File::Error error = base::File::FILE_OK;
114 EXPECT_TRUE(base::CreateDirectoryAndGetError(path, &error)) << error;
115 base::FilePath prefs_filename =
116 path.Append(FILE_PATH_LITERAL("TestPreferences"));
117 base::FilePath extensions_install_dir =
118 path.Append(FILE_PATH_LITERAL("Extensions"));
119 EXPECT_TRUE(base::DeleteFile(extensions_install_dir, true));
120 EXPECT_TRUE(base::CreateDirectoryAndGetError(extensions_install_dir, &error))
121 << error;
122
123 params.profile_path = path;
124 params.pref_file = prefs_filename;
125 params.extensions_install_dir = extensions_install_dir;
126 return params;
127}
128
129void ExtensionServiceTestBase::InitializeExtensionService(
130 const ExtensionServiceTestBase::ExtensionServiceInitParams& params) {
131 profile_ = BuildTestingProfile(params);
132 CreateExtensionService(params);
133
134 extensions_install_dir_ = params.extensions_install_dir;
135 registry_ = ExtensionRegistry::Get(profile_.get());
136
137 // Garbage collector is typically NULL during tests, so give it a build.
138 ExtensionGarbageCollectorFactory::GetInstance()->SetTestingFactoryAndUse(
Sylvain Defresne711ff6b2018-10-04 12:33:54139 profile_.get(),
140 base::BindRepeating(&ExtensionGarbageCollectorFactory::BuildInstanceFor));
[email protected]f484f8d52014-06-12 08:38:18141}
142
143void ExtensionServiceTestBase::InitializeEmptyExtensionService() {
144 InitializeExtensionService(CreateDefaultInitParams());
145}
146
147void ExtensionServiceTestBase::InitializeInstalledExtensionService(
148 const base::FilePath& prefs_file,
149 const base::FilePath& source_install_dir) {
150 ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
vabr9142fe22016-09-08 13:19:22151 base::FilePath path = temp_dir_.GetPath();
[email protected]f484f8d52014-06-12 08:38:18152
153 path = path.Append(FILE_PATH_LITERAL("TestingExtensionsPath"));
154 ASSERT_TRUE(base::DeleteFile(path, true));
155
156 base::File::Error error = base::File::FILE_OK;
157 ASSERT_TRUE(base::CreateDirectoryAndGetError(path, &error)) << error;
158
159 base::FilePath temp_prefs = path.Append(chrome::kPreferencesFilename);
160 ASSERT_TRUE(base::CopyFile(prefs_file, temp_prefs));
161
162 base::FilePath extensions_install_dir =
163 path.Append(FILE_PATH_LITERAL("Extensions"));
164 ASSERT_TRUE(base::DeleteFile(extensions_install_dir, true));
165 ASSERT_TRUE(
166 base::CopyDirectory(source_install_dir, extensions_install_dir, true));
167
168 ExtensionServiceInitParams params;
169 params.profile_path = path;
170 params.pref_file = temp_prefs;
171 params.extensions_install_dir = extensions_install_dir;
172 InitializeExtensionService(params);
173}
174
175void ExtensionServiceTestBase::InitializeGoodInstalledExtensionService() {
176 base::FilePath source_install_dir =
177 data_dir_.AppendASCII("good").AppendASCII("Extensions");
178 base::FilePath pref_path =
179 source_install_dir.DirName().Append(chrome::kPreferencesFilename);
180 InitializeInstalledExtensionService(pref_path, source_install_dir);
181}
182
183void ExtensionServiceTestBase::InitializeExtensionServiceWithUpdater() {
184 ExtensionServiceInitParams params = CreateDefaultInitParams();
185 params.autoupdate_enabled = true;
186 InitializeExtensionService(params);
187 service_->updater()->Start();
[email protected]f484f8d52014-06-12 08:38:18188}
189
rdevlin.cronin7217be52017-03-24 20:47:05190void ExtensionServiceTestBase::
191 InitializeExtensionServiceWithExtensionsDisabled() {
192 ExtensionServiceInitParams params = CreateDefaultInitParams();
193 params.extensions_enabled = false;
194 InitializeExtensionService(params);
195}
196
treib9afc6212015-10-30 18:49:58197size_t ExtensionServiceTestBase::GetPrefKeyCount() {
198 const base::DictionaryValue* dict =
Arkadiusz Mlynarczykc4474d72018-01-11 14:45:56199 profile()->GetPrefs()->GetDictionary(pref_names::kExtensions);
treib9afc6212015-10-30 18:49:58200 if (!dict) {
201 ADD_FAILURE();
202 return 0;
203 }
204 return dict->size();
205}
206
207void ExtensionServiceTestBase::ValidatePrefKeyCount(size_t count) {
208 EXPECT_EQ(count, GetPrefKeyCount());
209}
210
211testing::AssertionResult ExtensionServiceTestBase::ValidateBooleanPref(
212 const std::string& extension_id,
213 const std::string& pref_path,
214 bool expected_val) {
215 std::string msg = base::StringPrintf("while checking: %s %s == %s",
216 extension_id.c_str(), pref_path.c_str(),
217 expected_val ? "true" : "false");
218
219 PrefService* prefs = profile()->GetPrefs();
220 const base::DictionaryValue* dict =
Arkadiusz Mlynarczykc4474d72018-01-11 14:45:56221 prefs->GetDictionary(pref_names::kExtensions);
treib9afc6212015-10-30 18:49:58222 if (!dict) {
223 return testing::AssertionFailure()
224 << "extension.settings does not exist " << msg;
225 }
226
227 const base::DictionaryValue* pref = NULL;
228 if (!dict->GetDictionary(extension_id, &pref)) {
229 return testing::AssertionFailure()
230 << "extension pref does not exist " << msg;
231 }
232
233 bool val = false;
234 if (!pref->GetBoolean(pref_path, &val)) {
235 return testing::AssertionFailure()
236 << pref_path << " pref not found " << msg;
237 }
238
239 return expected_val == val
240 ? testing::AssertionSuccess()
241 : testing::AssertionFailure() << "base::Value is incorrect " << msg;
242}
243
244void ExtensionServiceTestBase::ValidateIntegerPref(
245 const std::string& extension_id,
246 const std::string& pref_path,
247 int expected_val) {
248 std::string msg = base::StringPrintf("while checking: %s %s == %s",
249 extension_id.c_str(), pref_path.c_str(),
250 base::IntToString(expected_val).c_str());
251
252 PrefService* prefs = profile()->GetPrefs();
253 const base::DictionaryValue* dict =
Arkadiusz Mlynarczykc4474d72018-01-11 14:45:56254 prefs->GetDictionary(pref_names::kExtensions);
treib9afc6212015-10-30 18:49:58255 ASSERT_TRUE(dict != NULL) << msg;
256 const base::DictionaryValue* pref = NULL;
257 ASSERT_TRUE(dict->GetDictionary(extension_id, &pref)) << msg;
258 EXPECT_TRUE(pref != NULL) << msg;
259 int val;
260 ASSERT_TRUE(pref->GetInteger(pref_path, &val)) << msg;
261 EXPECT_EQ(expected_val, val) << msg;
262}
263
264void ExtensionServiceTestBase::ValidateStringPref(
265 const std::string& extension_id,
266 const std::string& pref_path,
267 const std::string& expected_val) {
268 std::string msg = base::StringPrintf("while checking: %s.manifest.%s == %s",
269 extension_id.c_str(), pref_path.c_str(),
270 expected_val.c_str());
271
272 const base::DictionaryValue* dict =
Arkadiusz Mlynarczykc4474d72018-01-11 14:45:56273 profile()->GetPrefs()->GetDictionary(pref_names::kExtensions);
treib9afc6212015-10-30 18:49:58274 ASSERT_TRUE(dict != NULL) << msg;
275 const base::DictionaryValue* pref = NULL;
276 std::string manifest_path = extension_id + ".manifest";
277 ASSERT_TRUE(dict->GetDictionary(manifest_path, &pref)) << msg;
278 EXPECT_TRUE(pref != NULL) << msg;
279 std::string val;
280 ASSERT_TRUE(pref->GetString(pref_path, &val)) << msg;
281 EXPECT_EQ(expected_val, val) << msg;
282}
283
[email protected]f484f8d52014-06-12 08:38:18284void ExtensionServiceTestBase::SetUp() {
Devlin Cronin9722a722017-12-16 03:35:10285 LoadErrorReporter::GetInstance()->ClearErrors();
Sebastien Marchand2ebd9252018-11-08 18:39:35286
287 // Force TabManager/TabLifecycleUnitSource creation.
288 g_browser_process->resource_coordinator_parts();
[email protected]f484f8d52014-06-12 08:38:18289}
290
Christian Dullweber64d38d082018-02-02 14:06:31291void ExtensionServiceTestBase::TearDown() {
292 if (profile_) {
293 auto* partition =
294 content::BrowserContext::GetDefaultStoragePartition(profile_.get());
295 if (partition)
296 partition->WaitForDeletionTasksForTesting();
297 }
298}
299
[email protected]f484f8d52014-06-12 08:38:18300void ExtensionServiceTestBase::SetUpTestCase() {
301 // Safe to call multiple times.
Devlin Cronin9722a722017-12-16 03:35:10302 LoadErrorReporter::Init(false); // no noisy errors.
[email protected]f484f8d52014-06-12 08:38:18303}
304
305// These are declared in the .cc so that all inheritors don't need to know
306// that TestingProfile derives Profile derives BrowserContext.
307content::BrowserContext* ExtensionServiceTestBase::browser_context() {
308 return profile_.get();
309}
310
311Profile* ExtensionServiceTestBase::profile() {
312 return profile_.get();
313}
314
pmarko6e36b4632016-12-13 17:45:50315sync_preferences::TestingPrefServiceSyncable*
316ExtensionServiceTestBase::testing_pref_service() {
317 return profile_->GetTestingPrefService();
318}
319
[email protected]f484f8d52014-06-12 08:38:18320void ExtensionServiceTestBase::CreateExtensionService(
321 const ExtensionServiceInitParams& params) {
322 TestExtensionSystem* system =
323 static_cast<TestExtensionSystem*>(ExtensionSystem::Get(profile_.get()));
juncaicf523332015-06-04 00:14:04324 if (!params.is_first_run)
325 ExtensionPrefs::Get(profile_.get())->SetAlertSystemFirstRun();
[email protected]f484f8d52014-06-12 08:38:18326
rdevlin.cronin7217be52017-03-24 20:47:05327 service_ = system->CreateExtensionService(
328 base::CommandLine::ForCurrentProcess(), params.extensions_install_dir,
329 params.autoupdate_enabled, params.extensions_enabled);
[email protected]f484f8d52014-06-12 08:38:18330
jam726de9f2015-06-02 15:36:06331 service_->component_loader()->set_ignore_whitelist_for_testing(true);
[email protected]f484f8d52014-06-12 08:38:18332
333 // When we start up, we want to make sure there is no external provider,
334 // since the ExtensionService on Windows will use the Registry as a default
335 // provider and if there is something already registered there then it will
336 // interfere with the tests. Those tests that need an external provider
337 // will register one specifically.
338 service_->ClearProvidersForTesting();
339
xiyuanf6a4c6a62016-04-19 18:14:54340 service_->RegisterInstallGate(ExtensionPrefs::DELAY_REASON_WAIT_FOR_IMPORTS,
341 service_->shared_module_service());
342
[email protected]f484f8d52014-06-12 08:38:18343#if defined(OS_CHROMEOS)
344 InstallLimiter::Get(profile_.get())->DisableForTest();
345#endif
346}
347
348} // namespace extensions