blob: 45fe588e784bdfa4aae32b17ece984275c6e9f81 [file] [log] [blame]
[email protected]fd3df7782014-05-08 23:54:271// 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
asargent678123d22015-07-31 23:24:105#include <list>
Jinho Bangb5216cec2018-01-17 19:43:116#include <memory>
asargent678123d22015-07-31 23:24:107#include <set>
8#include <string>
9
asargent6014bdf2016-11-30 21:50:1610#include "base/bind_helpers.h"
asargent56282ab72016-09-09 16:58:0311#include "base/callback_helpers.h"
avia2f4804a2015-12-24 23:11:1312#include "base/macros.h"
asargent56282ab72016-09-09 16:58:0313#include "base/strings/string_split.h"
Minh X. Nguyen5c83226102018-04-19 16:10:2514#include "base/test/scoped_feature_list.h"
jam3f2d3932017-04-26 20:28:5115#include "base/threading/thread_restrictions.h"
asargent56282ab72016-09-09 16:58:0316#include "base/threading/thread_task_runner_handle.h"
asargent0de8a8bc2016-11-22 22:58:0217#include "chrome/browser/extensions/browsertest_util.h"
asargent6014bdf2016-11-30 21:50:1618#include "chrome/browser/extensions/chrome_content_verifier_delegate.h"
Minh X. Nguyen5c83226102018-04-19 16:10:2519#include "chrome/browser/extensions/content_verifier_test_utils.h"
[email protected]fd3df7782014-05-08 23:54:2720#include "chrome/browser/extensions/extension_browsertest.h"
asargent0de8a8bc2016-11-22 22:58:0221#include "chrome/browser/extensions/extension_management_test_util.h"
asargent56282ab72016-09-09 16:58:0322#include "chrome/browser/extensions/extension_service.h"
lazyboy77214d3c2017-04-04 16:46:1223#include "chrome/browser/extensions/policy_extension_reinstaller.h"
Istiaque Ahmed195fd5c2018-01-31 19:24:1324#include "chrome/test/base/ui_test_utils.h"
asargent0de8a8bc2016-11-22 22:58:0225#include "components/policy/core/browser/browser_policy_connector.h"
26#include "components/policy/core/common/mock_configuration_policy_provider.h"
Justin Donnelly5ce949f2017-05-12 22:03:3827#include "content/public/common/browser_side_navigation_policy.h"
[email protected]fd3df7782014-05-08 23:54:2728#include "content/public/test/test_utils.h"
asargent678123d22015-07-31 23:24:1029#include "extensions/browser/content_verifier.h"
Istiaque Ahmed584fe142018-03-13 09:19:0430#include "extensions/browser/content_verifier/test_utils.h"
[email protected]fd3df7782014-05-08 23:54:2731#include "extensions/browser/content_verify_job.h"
asargent56282ab72016-09-09 16:58:0332#include "extensions/browser/crx_file_info.h"
[email protected]fd3df7782014-05-08 23:54:2733#include "extensions/browser/extension_prefs.h"
34#include "extensions/browser/extension_registry.h"
asargent56282ab72016-09-09 16:58:0335#include "extensions/browser/external_install_info.h"
asargent56282ab72016-09-09 16:58:0336#include "extensions/browser/management_policy.h"
Minh X. Nguyen5c83226102018-04-19 16:10:2537#include "extensions/browser/mock_external_provider.h"
Istiaque Ahmed93081902018-02-02 05:36:2938#include "extensions/browser/test_extension_registry_observer.h"
asargent56282ab72016-09-09 16:58:0339#include "extensions/browser/updater/extension_downloader.h"
40#include "extensions/browser/updater/extension_downloader_test_delegate.h"
41#include "extensions/browser/updater/manifest_fetch_data.h"
Minh X. Nguyen5c83226102018-04-19 16:10:2542#include "extensions/common/extension_features.h"
asargent56282ab72016-09-09 16:58:0343#include "extensions/common/extension_urls.h"
[email protected]fd3df7782014-05-08 23:54:2744
45namespace extensions {
46
[email protected]fd3df7782014-05-08 23:54:2747class ContentVerifierTest : public ExtensionBrowserTest {
48 public:
49 ContentVerifierTest() {}
dcheng72191812014-10-28 20:49:5650 ~ContentVerifierTest() override {}
[email protected]fd3df7782014-05-08 23:54:2751
Istiaque Ahmed4c7b9d22018-03-20 02:13:3852 void SetUp() override {
Minh X. Nguyen5c83226102018-04-19 16:10:2553 scoped_feature_list_.InitAndDisableFeature(
Mostyn Bramley-Mooreb6a37c62018-09-04 21:43:3554 extensions_features::kNewExtensionUpdaterService);
Istiaque Ahmed4c7b9d22018-03-20 02:13:3855 // Override content verification mode before ExtensionSystemImpl initializes
56 // ChromeContentVerifierDelegate.
57 ChromeContentVerifierDelegate::SetDefaultModeForTesting(
58 ContentVerifierDelegate::ENFORCE);
59
60 ExtensionBrowserTest::SetUp();
61 }
62
63 void TearDown() override {
64 ExtensionBrowserTest::TearDown();
65 ChromeContentVerifierDelegate::SetDefaultModeForTesting(base::nullopt);
[email protected]fd3df7782014-05-08 23:54:2766 }
67
probergee8f8c7502017-10-03 22:19:3368 bool ShouldEnableContentVerification() override { return true; }
69
lazyboyd05d1e82017-04-24 21:20:4270 void TestContentScriptExtension(const std::string& crx_relpath,
71 const std::string& id,
72 const std::string& script_relpath) {
73 VerifierObserver verifier_observer;
74
75 // Install the extension with content scripts. The initial read of the
76 // content scripts will fail verification because they are read before the
77 // content verification system has completed a one-time processing of the
78 // expected hashes. (The extension only contains the root level hashes of
79 // the merkle tree, but the content verification system builds the entire
80 // tree and caches it in the extension install directory - see
81 // ContentHashFetcher for more details).
82 const Extension* extension = InstallExtensionFromWebstore(
83 test_data_dir_.AppendASCII(crx_relpath), 1);
84 ASSERT_TRUE(extension);
85 EXPECT_EQ(id, extension->id());
86
87 // Wait for the content verification code to finish processing the hashes.
88 if (!base::ContainsKey(verifier_observer.completed_fetches(), id))
89 verifier_observer.WaitForFetchComplete(id);
90
91 // Now disable the extension, since content scripts are read at enable time,
92 // set up our job observer, and re-enable, expecting a success this time.
93 DisableExtension(id);
Istiaque Ahmed584fe142018-03-13 09:19:0494 using Result = TestContentVerifyJobObserver::Result;
95 TestContentVerifyJobObserver job_observer;
lazyboyd05d1e82017-04-24 21:20:4296 base::FilePath script_relfilepath =
97 base::FilePath().AppendASCII(script_relpath);
Istiaque Ahmed584fe142018-03-13 09:19:0498 job_observer.ExpectJobResult(id, script_relfilepath, Result::SUCCESS);
lazyboyd05d1e82017-04-24 21:20:4299 EnableExtension(id);
100 EXPECT_TRUE(job_observer.WaitForExpectedJobs());
101
102 // Now alter the contents of the content script, reload the extension, and
103 // expect to see a job failure due to the content script content hash not
104 // being what was signed by the webstore.
105 base::FilePath scriptfile = extension->path().AppendASCII(script_relpath);
106 std::string extra = "some_extra_function_call();";
jam3f2d3932017-04-26 20:28:51107 {
Francois Doraye6fb2d02017-10-18 21:29:13108 base::ScopedAllowBlockingForTesting allow_blocking;
jam3f2d3932017-04-26 20:28:51109 ASSERT_TRUE(base::AppendToFile(scriptfile, extra.data(), extra.size()));
110 }
lazyboyd05d1e82017-04-24 21:20:42111 DisableExtension(id);
Istiaque Ahmed584fe142018-03-13 09:19:04112 job_observer.ExpectJobResult(id, script_relfilepath, Result::FAILURE);
lazyboyd05d1e82017-04-24 21:20:42113 EnableExtension(id);
114 EXPECT_TRUE(job_observer.WaitForExpectedJobs());
115 }
Minh X. Nguyen5c83226102018-04-19 16:10:25116
117 protected:
118 base::test::ScopedFeatureList scoped_feature_list_;
[email protected]fd3df7782014-05-08 23:54:27119};
120
Istiaque Ahmed231c6bd2018-03-29 05:31:58121IN_PROC_BROWSER_TEST_F(ContentVerifierTest, DotSlashPaths) {
Istiaque Ahmed584fe142018-03-13 09:19:04122 TestContentVerifyJobObserver job_observer;
asargent7cc29ce32014-10-09 21:27:57123 std::string id = "hoipipabpcoomfapcecilckodldhmpgl";
124
Istiaque Ahmed584fe142018-03-13 09:19:04125 using Result = TestContentVerifyJobObserver::Result;
asargent7cc29ce32014-10-09 21:27:57126 job_observer.ExpectJobResult(
Istiaque Ahmed584fe142018-03-13 09:19:04127 id, base::FilePath(FILE_PATH_LITERAL("background.js")), Result::SUCCESS);
128 job_observer.ExpectJobResult(
129 id, base::FilePath(FILE_PATH_LITERAL("page.html")), Result::SUCCESS);
asargent678123d22015-07-31 23:24:10130 job_observer.ExpectJobResult(id, base::FilePath(FILE_PATH_LITERAL("page.js")),
Istiaque Ahmed584fe142018-03-13 09:19:04131 Result::SUCCESS);
asargent7cc29ce32014-10-09 21:27:57132 job_observer.ExpectJobResult(
Istiaque Ahmed584fe142018-03-13 09:19:04133 id, base::FilePath(FILE_PATH_LITERAL("dir/page2.html")), Result::SUCCESS);
134 job_observer.ExpectJobResult(
135 id, base::FilePath(FILE_PATH_LITERAL("page2.js")), Result::SUCCESS);
asargent73d92c72015-09-10 19:20:12136 job_observer.ExpectJobResult(id, base::FilePath(FILE_PATH_LITERAL("cs1.js")),
Istiaque Ahmed584fe142018-03-13 09:19:04137 Result::SUCCESS);
asargent73d92c72015-09-10 19:20:12138 job_observer.ExpectJobResult(id, base::FilePath(FILE_PATH_LITERAL("cs2.js")),
Istiaque Ahmed584fe142018-03-13 09:19:04139 Result::SUCCESS);
asargent73d92c72015-09-10 19:20:12140
Istiaque Ahmed3641f523a2018-03-23 23:27:41141 auto verifier_observer = std::make_unique<VerifierObserver>();
asargent7cc29ce32014-10-09 21:27:57142
143 // Install a test extension we copied from the webstore that has actual
asargent73d92c72015-09-10 19:20:12144 // signatures, and contains paths with a leading "./" in various places.
asargent7cc29ce32014-10-09 21:27:57145 const Extension* extension = InstallExtensionFromWebstore(
146 test_data_dir_.AppendASCII("content_verifier/dot_slash_paths.crx"), 1);
147
148 ASSERT_TRUE(extension);
149 ASSERT_EQ(extension->id(), id);
150
asargent73d92c72015-09-10 19:20:12151 // The content scripts might fail verification the first time since the
152 // one-time processing might not be finished yet - if that's the case then
153 // we want to wait until that work is done.
Istiaque Ahmed3641f523a2018-03-23 23:27:41154 if (!base::ContainsKey(verifier_observer->completed_fetches(), id))
155 verifier_observer->WaitForFetchComplete(id);
156
157 // It is important to destroy |verifier_observer| here so that it doesn't see
158 // any fetch from EnableExtension call below (the observer pointer in
159 // content_verifier.cc isn't thread safe, so it might asynchronously call
160 // OnFetchComplete after this test's body executes).
161 verifier_observer.reset();
asargent73d92c72015-09-10 19:20:12162
Istiaque Ahmed231c6bd2018-03-29 05:31:58163 EXPECT_TRUE(job_observer.WaitForExpectedJobs());
164
165 // Set expectations for extension enablement below.
166 job_observer.ExpectJobResult(id, base::FilePath(FILE_PATH_LITERAL("cs1.js")),
167 Result::SUCCESS);
168 job_observer.ExpectJobResult(id, base::FilePath(FILE_PATH_LITERAL("cs2.js")),
169 Result::SUCCESS);
170
asargent73d92c72015-09-10 19:20:12171 // Now disable/re-enable the extension to cause the content scripts to be
172 // read again.
173 DisableExtension(id);
174 EnableExtension(id);
175
asargent7cc29ce32014-10-09 21:27:57176 EXPECT_TRUE(job_observer.WaitForExpectedJobs());
asargent7cc29ce32014-10-09 21:27:57177}
178
asargent678123d22015-07-31 23:24:10179IN_PROC_BROWSER_TEST_F(ContentVerifierTest, ContentScripts) {
lazyboyd05d1e82017-04-24 21:20:42180 TestContentScriptExtension("content_verifier/content_script.crx",
181 "jmllhlobpjcnnomjlipadejplhmheiif", "script.js");
182}
asargent678123d22015-07-31 23:24:10183
lazyboyd05d1e82017-04-24 21:20:42184IN_PROC_BROWSER_TEST_F(ContentVerifierTest, ContentScriptsInLocales) {
185 TestContentScriptExtension("content_verifier/content_script_locales.crx",
186 "jaghonccckpcikmliipifpoodmeofoon",
187 "_locales/en/content_script.js");
asargent678123d22015-07-31 23:24:10188}
189
asargent56282ab72016-09-09 16:58:03190// Tests the case of a corrupt extension that is force-installed by policy and
191// should not be allowed to be manually uninstalled/disabled by the user.
192IN_PROC_BROWSER_TEST_F(ContentVerifierTest, PolicyCorrupted) {
193 ExtensionSystem* system = ExtensionSystem::Get(profile());
194 ExtensionService* service = system->extension_service();
195
196 // The id of our test extension.
Istiaque Ahmed93081902018-02-02 05:36:29197 ExtensionId kExtensionId("npnbmohejbjohgpjnmjagbafnjhkmgko");
asargent56282ab72016-09-09 16:58:03198
199 // Setup fake policy and update check objects.
Minh X. Nguyen5c83226102018-04-19 16:10:25200 content_verifier_test::ForceInstallProvider policy(kExtensionId);
201 content_verifier_test::DownloaderTestDelegate downloader;
asargent56282ab72016-09-09 16:58:03202 system->management_policy()->RegisterProvider(&policy);
203 ExtensionDownloader::set_test_delegate(&downloader);
Minh X. Nguyen5c83226102018-04-19 16:10:25204 auto external_provider = std::make_unique<MockExternalProvider>(
205 service, Manifest::EXTERNAL_POLICY_DOWNLOAD);
206 external_provider->UpdateOrAddExtension(
207 std::make_unique<ExternalInstallInfoUpdateUrl>(
208 kExtensionId, std::string() /* install_parameter */,
209 extension_urls::GetWebstoreUpdateUrl(),
210 Manifest::EXTERNAL_POLICY_DOWNLOAD, 0 /* creation_flags */,
211 true /* mark_acknowldged */));
212 service->AddProviderForTesting(std::move(external_provider));
asargent56282ab72016-09-09 16:58:03213
214 base::FilePath crx_path =
215 test_data_dir_.AppendASCII("content_verifier/v1.crx");
216 const Extension* extension =
217 InstallExtension(crx_path, 1, Manifest::EXTERNAL_POLICY_DOWNLOAD);
Istiaque Ahmed93081902018-02-02 05:36:29218 ASSERT_TRUE(extension);
asargent56282ab72016-09-09 16:58:03219
Istiaque Ahmed93081902018-02-02 05:36:29220 downloader.AddResponse(kExtensionId, extension->VersionString(), crx_path);
221 EXPECT_EQ(kExtensionId, extension->id());
asargent56282ab72016-09-09 16:58:03222
Istiaque Ahmed93081902018-02-02 05:36:29223 TestExtensionRegistryObserver registry_observer(
224 ExtensionRegistry::Get(profile()), kExtensionId);
asargent56282ab72016-09-09 16:58:03225 ContentVerifier* verifier = system->content_verifier();
Istiaque Ahmed93081902018-02-02 05:36:29226 verifier->VerifyFailed(kExtensionId, ContentVerifyJob::HASH_MISMATCH);
asargent56282ab72016-09-09 16:58:03227
228 // Make sure the extension first got disabled due to corruption.
Istiaque Ahmed93081902018-02-02 05:36:29229 EXPECT_TRUE(registry_observer.WaitForExtensionUnloaded());
asargent56282ab72016-09-09 16:58:03230 ExtensionPrefs* prefs = ExtensionPrefs::Get(profile());
Istiaque Ahmed93081902018-02-02 05:36:29231 int reasons = prefs->GetDisableReasons(kExtensionId);
Minh X. Nguyen45479012017-08-18 21:35:36232 EXPECT_TRUE(reasons & disable_reason::DISABLE_CORRUPTED);
asargent56282ab72016-09-09 16:58:03233
234 // Make sure the extension then got re-installed, and that after reinstall it
235 // is no longer disabled due to corruption.
Istiaque Ahmed93081902018-02-02 05:36:29236 EXPECT_TRUE(registry_observer.WaitForExtensionInstalled());
237
238 reasons = prefs->GetDisableReasons(kExtensionId);
Minh X. Nguyen45479012017-08-18 21:35:36239 EXPECT_FALSE(reasons & disable_reason::DISABLE_CORRUPTED);
asargent56282ab72016-09-09 16:58:03240
241 // Make sure that the update check request properly included a parameter
242 // indicating that this was a corrupt policy reinstall.
243 bool found = false;
244 for (const auto& request : downloader.requests()) {
Istiaque Ahmed93081902018-02-02 05:36:29245 if (request->Includes(kExtensionId)) {
asargent56282ab72016-09-09 16:58:03246 std::string query = request->full_url().query();
247 for (const auto& part : base::SplitString(
248 query, "&", base::KEEP_WHITESPACE, base::SPLIT_WANT_ALL)) {
249 if (base::StartsWith(part, "x=", base::CompareCase::SENSITIVE) &&
Istiaque Ahmed93081902018-02-02 05:36:29250 part.find(std::string("id%3D") + kExtensionId) !=
251 std::string::npos) {
asargent56282ab72016-09-09 16:58:03252 found = true;
253 EXPECT_NE(std::string::npos, part.find("installsource%3Dreinstall"));
254 }
255 }
256 }
257 }
258 EXPECT_TRUE(found);
259}
260
Istiaque Ahmed195fd5c2018-01-31 19:24:13261// Tests that verification failure during navigating to an extension resource
262// correctly disables the extension.
263IN_PROC_BROWSER_TEST_F(ContentVerifierTest, VerificationFailureOnNavigate) {
Istiaque Ahmed195fd5c2018-01-31 19:24:13264 const Extension* extension = InstallExtensionFromWebstore(
265 test_data_dir_.AppendASCII("content_verifier/dot_slash_paths.crx"), 1);
266 ASSERT_TRUE(extension);
267 const ExtensionId kExtensionId = extension->id();
268 const base::FilePath::CharType kResource[] = FILE_PATH_LITERAL("page.html");
269 {
270 // Modify content so that content verification fails.
271 base::ScopedAllowBlockingForTesting allow_blocking;
272 base::FilePath real_path = extension->path().Append(kResource);
273 std::string extra = "some_extra_function_call();";
274 ASSERT_TRUE(base::AppendToFile(real_path, extra.data(), extra.size()));
275 }
276
277 GURL page_url = extension->GetResourceURL("page.html");
Istiaque Ahmed93081902018-02-02 05:36:29278 TestExtensionRegistryObserver unload_observer(
279 ExtensionRegistry::Get(profile()), kExtensionId);
Istiaque Ahmed195fd5c2018-01-31 19:24:13280 // Wait for 0 navigations to complete because with PlzNavigate it's racy
281 // when the didstop IPC arrives relative to the tab being closed. The
282 // wait call below is what the tests care about.
283 ui_test_utils::NavigateToURLWithDispositionBlockUntilNavigationsComplete(
284 browser(), page_url, 0, WindowOpenDisposition::NEW_FOREGROUND_TAB,
285 ui_test_utils::BROWSER_TEST_NONE);
Istiaque Ahmed93081902018-02-02 05:36:29286 EXPECT_TRUE(unload_observer.WaitForExtensionUnloaded());
Istiaque Ahmed195fd5c2018-01-31 19:24:13287 ExtensionPrefs* prefs = ExtensionPrefs::Get(profile());
288 int reasons = prefs->GetDisableReasons(kExtensionId);
289 EXPECT_TRUE(reasons & disable_reason::DISABLE_CORRUPTED);
290}
291
asargent0de8a8bc2016-11-22 22:58:02292class ContentVerifierPolicyTest : public ContentVerifierTest {
293 public:
294 // We need to do this work here because the force-install policy values are
295 // checked pretty early on in the startup of the ExtensionService, which
296 // happens between SetUpInProcessBrowserTestFixture and SetUpOnMainThread.
297 void SetUpInProcessBrowserTestFixture() override {
298 ContentVerifierTest::SetUpInProcessBrowserTestFixture();
299
300 EXPECT_CALL(policy_provider_, IsInitializationComplete(testing::_))
301 .WillRepeatedly(testing::Return(true));
302
303 policy::BrowserPolicyConnector::SetPolicyProviderForTesting(
304 &policy_provider_);
305 ExtensionManagementPolicyUpdater management_policy(&policy_provider_);
306 management_policy.SetIndividualExtensionAutoInstalled(
307 id_, extension_urls::kChromeWebstoreUpdateURL, true /* forced */);
308
309 ExtensionDownloader::set_test_delegate(&downloader_);
310 base::FilePath crx_path =
311 test_data_dir_.AppendASCII("content_verifier/v1.crx");
312 std::string version = "2";
313 downloader_.AddResponse(id_, version, crx_path);
314 }
315
316 void SetUpOnMainThread() override {
317 extensions::browsertest_util::CreateAndInitializeLocalCache();
318 }
319
320 protected:
321 // The id of the extension we want to have force-installed.
322 std::string id_ = "npnbmohejbjohgpjnmjagbafnjhkmgko";
323
324 private:
325 policy::MockConfigurationPolicyProvider policy_provider_;
Minh X. Nguyen5c83226102018-04-19 16:10:25326 content_verifier_test::DownloaderTestDelegate downloader_;
asargent0de8a8bc2016-11-22 22:58:02327};
328
329// We want to test what happens at startup with a corroption-disabled policy
330// force installed extension. So we set that up in the PRE test here.
331IN_PROC_BROWSER_TEST_F(ContentVerifierPolicyTest,
asargentba52f322016-11-30 18:26:06332 PRE_PolicyCorruptedOnStartup) {
asargent0de8a8bc2016-11-22 22:58:02333 ExtensionRegistry* registry = ExtensionRegistry::Get(profile());
Istiaque Ahmed93081902018-02-02 05:36:29334 TestExtensionRegistryObserver registry_observer(registry, id_);
asargent0de8a8bc2016-11-22 22:58:02335
336 // Wait for the extension to be installed by policy we set up in
337 // SetUpInProcessBrowserTestFixture.
Istiaque Ahmed93081902018-02-02 05:36:29338 if (!registry->GetInstalledExtension(id_))
339 EXPECT_TRUE(registry_observer.WaitForExtensionInstalled());
asargent0de8a8bc2016-11-22 22:58:02340
341 // Simulate corruption of the extension so that we can test what happens
342 // at startup in the non-PRE test.
343 ExtensionSystem* system = ExtensionSystem::Get(profile());
344 ContentVerifier* verifier = system->content_verifier();
345 verifier->VerifyFailed(id_, ContentVerifyJob::HASH_MISMATCH);
Istiaque Ahmed93081902018-02-02 05:36:29346 EXPECT_TRUE(registry_observer.WaitForExtensionUnloaded());
asargent0de8a8bc2016-11-22 22:58:02347 ExtensionPrefs* prefs = ExtensionPrefs::Get(profile());
348 int reasons = prefs->GetDisableReasons(id_);
Minh X. Nguyen45479012017-08-18 21:35:36349 EXPECT_TRUE(reasons & disable_reason::DISABLE_CORRUPTED);
asargent0de8a8bc2016-11-22 22:58:02350}
351
352// Now actually test what happens on the next startup after the PRE test above.
asargentba52f322016-11-30 18:26:06353IN_PROC_BROWSER_TEST_F(ContentVerifierPolicyTest, PolicyCorruptedOnStartup) {
354 // Depdending on timing, the extension may have already been reinstalled
355 // between SetUpInProcessBrowserTestFixture and now (usually not during local
356 // testing on a developer machine, but sometimes on a heavily loaded system
357 // such as the build waterfall / trybots). If the reinstall didn't already
358 // happen, wait for it.
asargent0de8a8bc2016-11-22 22:58:02359 ExtensionPrefs* prefs = ExtensionPrefs::Get(profile());
asargent0de8a8bc2016-11-22 22:58:02360 ExtensionRegistry* registry = ExtensionRegistry::Get(profile());
asargentba52f322016-11-30 18:26:06361 int disable_reasons = prefs->GetDisableReasons(id_);
Minh X. Nguyen45479012017-08-18 21:35:36362 if (disable_reasons & disable_reason::DISABLE_CORRUPTED) {
Istiaque Ahmed93081902018-02-02 05:36:29363 TestExtensionRegistryObserver registry_observer(registry, id_);
364 EXPECT_TRUE(registry_observer.WaitForExtensionInstalled());
asargentba52f322016-11-30 18:26:06365 disable_reasons = prefs->GetDisableReasons(id_);
366 }
Minh X. Nguyen45479012017-08-18 21:35:36367 EXPECT_FALSE(disable_reasons & disable_reason::DISABLE_CORRUPTED);
asargentba52f322016-11-30 18:26:06368 EXPECT_TRUE(registry->enabled_extensions().Contains(id_));
asargent0de8a8bc2016-11-22 22:58:02369}
370
asargent6014bdf2016-11-30 21:50:16371IN_PROC_BROWSER_TEST_F(ContentVerifierPolicyTest, Backoff) {
372 ExtensionRegistry* registry = ExtensionRegistry::Get(profile());
373 ExtensionSystem* system = ExtensionSystem::Get(profile());
asargent6014bdf2016-11-30 21:50:16374 ContentVerifier* verifier = system->content_verifier();
375
376 // Wait for the extension to be installed by the policy we set up in
377 // SetUpInProcessBrowserTestFixture.
378 if (!registry->GetInstalledExtension(id_)) {
Istiaque Ahmed93081902018-02-02 05:36:29379 TestExtensionRegistryObserver registry_observer(registry, id_);
380 EXPECT_TRUE(registry_observer.WaitForExtensionInstalled());
asargent6014bdf2016-11-30 21:50:16381 }
382
383 // Setup to intercept reinstall action, so we can see what the delay would
384 // have been for the real action.
Minh X. Nguyen5c83226102018-04-19 16:10:25385 content_verifier_test::DelayTracker delay_tracker;
asargent6014bdf2016-11-30 21:50:16386
387 // Do 4 iterations of disabling followed by reinstall.
388 const size_t iterations = 4;
389 for (size_t i = 0; i < iterations; i++) {
Istiaque Ahmed93081902018-02-02 05:36:29390 TestExtensionRegistryObserver registry_observer(registry, id_);
asargent6014bdf2016-11-30 21:50:16391 verifier->VerifyFailed(id_, ContentVerifyJob::HASH_MISMATCH);
Istiaque Ahmed93081902018-02-02 05:36:29392 EXPECT_TRUE(registry_observer.WaitForExtensionUnloaded());
lazyboy77214d3c2017-04-04 16:46:12393 // Resolve the request to |delay_tracker|, so the reinstallation can
394 // proceed.
395 delay_tracker.Proceed();
Istiaque Ahmed93081902018-02-02 05:36:29396 EXPECT_TRUE(registry_observer.WaitForExtensionInstalled());
asargent6014bdf2016-11-30 21:50:16397 }
398 const std::vector<base::TimeDelta>& calls = delay_tracker.calls();
399
lazyboy77214d3c2017-04-04 16:46:12400 // After |delay_tracker| resolves the 4 (|iterations|) reinstallation
401 // requests, it will get an additional request (right away) for retrying
402 // reinstallation.
403 // Note: the additional request in non-test environment will arrive with
404 // a (backoff) delay. But during test, |delay_tracker| issues the request
405 // immediately.
406 ASSERT_EQ(iterations, calls.size() - 1);
asargent6014bdf2016-11-30 21:50:16407 // Assert that the first reinstall action happened with a delay of 0, and
408 // then kept growing each additional time.
asargent6014bdf2016-11-30 21:50:16409 EXPECT_EQ(base::TimeDelta(), delay_tracker.calls()[0]);
410 for (size_t i = 1; i < delay_tracker.calls().size(); i++) {
411 EXPECT_LT(calls[i - 1], calls[i]);
412 }
413}
414
lazyboy77214d3c2017-04-04 16:46:12415// Tests that if CheckForExternalUpdates() fails, then we retry reinstalling
416// corrupted policy extensions. For example: if network is unavailable,
417// CheckForExternalUpdates() will fail.
418IN_PROC_BROWSER_TEST_F(ContentVerifierPolicyTest, FailedUpdateRetries) {
419 ExtensionRegistry* registry = ExtensionRegistry::Get(profile());
420 ExtensionSystem* system = ExtensionSystem::Get(profile());
421 ExtensionService* service = system->extension_service();
422 ContentVerifier* verifier = system->content_verifier();
423
424 // Wait for the extension to be installed by the policy we set up in
425 // SetUpInProcessBrowserTestFixture.
426 if (!registry->GetInstalledExtension(id_)) {
Istiaque Ahmed93081902018-02-02 05:36:29427 TestExtensionRegistryObserver registry_observer(registry, id_);
428 EXPECT_TRUE(registry_observer.WaitForExtensionInstalled());
lazyboy77214d3c2017-04-04 16:46:12429 }
430
Minh X. Nguyen5c83226102018-04-19 16:10:25431 content_verifier_test::DelayTracker delay_tracker;
lazyboy77214d3c2017-04-04 16:46:12432 service->set_external_updates_disabled_for_test(true);
Istiaque Ahmed93081902018-02-02 05:36:29433 TestExtensionRegistryObserver registry_observer(registry, id_);
lazyboy77214d3c2017-04-04 16:46:12434 verifier->VerifyFailed(id_, ContentVerifyJob::HASH_MISMATCH);
Istiaque Ahmed93081902018-02-02 05:36:29435 EXPECT_TRUE(registry_observer.WaitForExtensionUnloaded());
lazyboy77214d3c2017-04-04 16:46:12436
437 const std::vector<base::TimeDelta>& calls = delay_tracker.calls();
438 ASSERT_EQ(1u, calls.size());
439 EXPECT_EQ(base::TimeDelta(), delay_tracker.calls()[0]);
440
441 delay_tracker.Proceed();
442
443 // Remove the override and set ExtensionService to update again. The extension
444 // should be now installed.
445 PolicyExtensionReinstaller::set_policy_reinstall_action_for_test(nullptr);
446 service->set_external_updates_disabled_for_test(false);
447 delay_tracker.Proceed();
448
Istiaque Ahmed93081902018-02-02 05:36:29449 EXPECT_TRUE(registry_observer.WaitForExtensionInstalled());
lazyboy77214d3c2017-04-04 16:46:12450}
451
[email protected]fd3df7782014-05-08 23:54:27452} // namespace extensions