1 // 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.
5 #include "base/scoped_observer.h"
6 #include "chrome/browser/extensions/extension_browsertest.h"
7 #include "chrome/common/chrome_switches.h"
8 #include "content/public/test/test_utils.h"
9 #include "extensions/browser/content_verify_job.h"
10 #include "extensions/browser/extension_prefs.h"
11 #include "extensions/browser/extension_registry.h"
12 #include "extensions/browser/extension_registry_observer.h"
14 namespace extensions {
18 // Helper for observing extension unloads.
19 class UnloadObserver : public ExtensionRegistryObserver {
21 explicit UnloadObserver(ExtensionRegistry* registry) : observer_(this) {
22 observer_.Add(registry);
24 virtual ~UnloadObserver() {}
26 void WaitForUnload(const ExtensionId& id) {
27 if (ContainsKey(observed_, id))
30 ASSERT_TRUE(loop_runner_.get() == NULL);
32 loop_runner_ = new content::MessageLoopRunner();
36 virtual void OnExtensionUnloaded(
37 content::BrowserContext* browser_context,
38 const Extension* extension,
39 UnloadedExtensionInfo::Reason reason) OVERRIDE {
40 observed_.insert(extension->id());
41 if (awaited_id_ == extension->id())
46 ExtensionId awaited_id_;
47 std::set<ExtensionId> observed_;
48 scoped_refptr<content::MessageLoopRunner> loop_runner_;
49 ScopedObserver<ExtensionRegistry, UnloadObserver> observer_;
52 // Helper for forcing ContentVerifyJob's to return an error.
53 class JobDelegate : public ContentVerifyJob::TestDelegate {
55 JobDelegate() : fail_next_read_(false), fail_next_done_(false) {}
57 virtual ~JobDelegate() {}
59 void set_id(const ExtensionId& id) { id_ = id; }
60 void fail_next_read() { fail_next_read_ = true; }
61 void fail_next_done() { fail_next_done_ = true; }
63 virtual ContentVerifyJob::FailureReason BytesRead(const ExtensionId& id,
65 const char* data) OVERRIDE {
66 if (id == id_ && fail_next_read_) {
67 fail_next_read_ = false;
68 return ContentVerifyJob::HASH_MISMATCH;
70 return ContentVerifyJob::NONE;
73 virtual ContentVerifyJob::FailureReason DoneReading(
74 const ExtensionId& id) OVERRIDE {
75 if (id == id_ && fail_next_done_) {
76 fail_next_done_ = false;
77 return ContentVerifyJob::HASH_MISMATCH;
79 return ContentVerifyJob::NONE;
83 DISALLOW_COPY_AND_ASSIGN(JobDelegate);
92 class ContentVerifierTest : public ExtensionBrowserTest {
94 ContentVerifierTest() {}
95 virtual ~ContentVerifierTest() {}
97 virtual void SetUpCommandLine(base::CommandLine* command_line) OVERRIDE {
98 ExtensionBrowserTest::SetUpCommandLine(command_line);
99 command_line->AppendSwitchASCII(
100 switches::kExtensionContentVerification,
101 switches::kExtensionContentVerificationEnforce);
104 // Setup our unload observer and JobDelegate, and install a test extension.
105 virtual void SetUpOnMainThread() OVERRIDE {
106 ExtensionBrowserTest::SetUpOnMainThread();
107 unload_observer_.reset(
108 new UnloadObserver(ExtensionRegistry::Get(profile())));
109 const Extension* extension = InstallExtensionFromWebstore(
110 test_data_dir_.AppendASCII("content_verifier/v1.crx"), 1);
111 ASSERT_TRUE(extension);
112 id_ = extension->id();
113 page_url_ = extension->GetResourceURL("page.html");
114 delegate_.set_id(id_);
115 ContentVerifyJob::SetDelegateForTests(&delegate_);
118 virtual void TearDownOnMainThread() OVERRIDE {
119 ContentVerifyJob::SetDelegateForTests(NULL);
120 ExtensionBrowserTest::TearDownOnMainThread();
123 virtual void OpenPageAndWaitForUnload() {
124 AddTabAtIndex(1, page_url_, ui::PAGE_TRANSITION_LINK);
125 unload_observer_->WaitForUnload(id_);
126 ExtensionPrefs* prefs = ExtensionPrefs::Get(profile());
127 int reasons = prefs->GetDisableReasons(id_);
128 EXPECT_TRUE(reasons & Extension::DISABLE_CORRUPTED);
130 // This needs to happen before the ExtensionRegistry gets deleted, which
131 // happens before TearDownOnMainThread is called.
132 unload_observer_.reset();
136 JobDelegate delegate_;
137 scoped_ptr<UnloadObserver> unload_observer_;
142 IN_PROC_BROWSER_TEST_F(ContentVerifierTest, FailOnRead) {
143 delegate_.fail_next_read();
144 OpenPageAndWaitForUnload();
147 IN_PROC_BROWSER_TEST_F(ContentVerifierTest, FailOnDone) {
148 delegate_.fail_next_done();
149 OpenPageAndWaitForUnload();
152 } // namespace extensions