Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(323)

Side by Side Diff: chrome/browser/extensions/extension_blacklist_browsertest.cc

Issue 11415216: Make Blacklist::IsBlacklist asynchronous (it will need to be for safe (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 8 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
1 // Copyright 2012 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 "base/run_loop.h"
6 #include "base/stringprintf.h"
7 #include "chrome/browser/extensions/blacklist.h"
8 #include "chrome/browser/extensions/extension_browsertest.h"
9 #include "chrome/browser/extensions/extension_service.h"
10 #include "chrome/browser/extensions/extension_system.h"
11 #include "chrome/browser/ui/browser.h"
12 #include "chrome/common/chrome_notification_types.h"
13 #include "chrome/common/extensions/extension.h"
14 #include "chrome/common/extensions/extension_constants.h"
15 #include "content/public/browser/notification_details.h"
16 #include "content/public/browser/notification_observer.h"
17 #include "content/public/browser/notification_registrar.h"
18 #include "content/public/browser/notification_source.h"
19
20 namespace extensions {
21
22 namespace {
23
24 // Records notifications, but only for extensions with specific IDs.
25 class FilteringNotificationObserver : public content::NotificationObserver {
26 public:
27 FilteringNotificationObserver(
28 content::NotificationSource source,
29 const std::set<std::string>& extension_ids)
30 : extension_ids_(extension_ids) {
31 registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_LOADED, source);
32 registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_INSTALLED, source);
33 registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_UNLOADED, source);
34 }
35
36 // Checks then clears notifications for our extensions.
37 testing::AssertionResult CheckNotifications(chrome::NotificationType type) {
38 return CheckNotifications(std::vector<chrome::NotificationType>(1, type));
39 }
40
41 // Checks then clears notifications for our extensions.
42 testing::AssertionResult CheckNotifications(chrome::NotificationType t1,
43 chrome::NotificationType t2) {
44 std::vector<chrome::NotificationType> types;
45 types.push_back(t1);
46 types.push_back(t2);
47 return CheckNotifications(types);
48 }
49
50 // Checks then clears notifications for our extensions.
51 testing::AssertionResult CheckNotifications(chrome::NotificationType t1,
52 chrome::NotificationType t2,
53 chrome::NotificationType t3,
54 chrome::NotificationType t4) {
55 std::vector<chrome::NotificationType> types;
56 types.push_back(t1);
57 types.push_back(t2);
58 types.push_back(t3);
59 types.push_back(t4);
60 return CheckNotifications(types);
61 }
62
63 private:
64 // content::NotificationObserver implementation.
65 virtual void Observe(int type,
66 const content::NotificationSource& source,
67 const content::NotificationDetails& details) OVERRIDE {
68 switch (type) {
69 case chrome::NOTIFICATION_EXTENSION_INSTALLED: {
70 const Extension* extension =
71 content::Details<const Extension>(details).ptr();
72 if (extension_ids_.count(extension->id()))
73 notifications_.push_back(static_cast<chrome::NotificationType>(type));
74 break;
75 }
76
77 case chrome::NOTIFICATION_EXTENSION_LOADED: {
78 const Extension* extension =
79 content::Details<const Extension>(details).ptr();
80 if (extension_ids_.count(extension->id()))
81 notifications_.push_back(static_cast<chrome::NotificationType>(type));
82 break;
83 }
84
85 case chrome::NOTIFICATION_EXTENSION_UNLOADED: {
86 UnloadedExtensionInfo* reason =
87 content::Details<UnloadedExtensionInfo>(details).ptr();
88 if (extension_ids_.count(reason->extension->id())) {
89 notifications_.push_back(static_cast<chrome::NotificationType>(type));
90 // The only way that extensions are unloaded in these tests is
91 // by blacklisting.
92 EXPECT_EQ(extension_misc::UNLOAD_REASON_BLACKLIST,
93 reason->reason);
94 }
95 break;
96 }
97
98 default:
99 NOTREACHED();
100 break;
101 }
102 }
103
104 // Checks then clears notifications for our extensions.
105 testing::AssertionResult CheckNotifications(
106 const std::vector<chrome::NotificationType>& types) {
107 testing::AssertionResult result = (notifications_ == types) ?
108 testing::AssertionSuccess() :
109 testing::AssertionFailure() << "Expected " << Str(types) << ", " <<
110 "Got " << Str(notifications_);
111 notifications_.clear();
112 return result;
113 }
114
115 std::string Str(const std::vector<chrome::NotificationType>& types) {
116 std::string str = "[";
117 bool needs_comma = false;
118 for (std::vector<chrome::NotificationType>::const_iterator it =
119 types.begin(); it != types.end(); ++it) {
120 if (needs_comma)
121 str += ",";
122 needs_comma = true;
123 str += base::StringPrintf("%d", *it);
124 }
125 return str + "]";
126 }
127
128 const std::set<std::string> extension_ids_;
129
130 std::vector<chrome::NotificationType> notifications_;
131
132 content::NotificationRegistrar registrar_;
133 };
134
135 // Stores the paths to CRX files of extensions, and the extension's ID.
136 // Use arbitrary extensions; we're just testing blacklisting behavior.
137 class CrxInfo {
138 public:
139 CrxInfo(const std::string& path, const std::string& id)
140 : path_(path), id_(id) {}
141
142 const std::string& path() { return path_; }
143 const std::string& id() { return id_; }
144
145 private:
146 const std::string path_;
147 const std::string id_;
148 };
149
150 } // namespace
151
152 class ExtensionBlacklistBrowserTest : public ExtensionBrowserTest {
153 public:
154 ExtensionBlacklistBrowserTest()
155 : info_a_("install/install.crx", "ogdbpbegnmindpdjfafpmpicikegejdj"),
156 info_b_("autoupdate/v1.crx", "ogjcoiohnmldgjemafoockdghcjciccf") {}
157
158 virtual ~ExtensionBlacklistBrowserTest() {}
159
160 protected:
161 // Returns whether |extension| is strictly installed: in ExtensionService's
162 // installed extensions, and not in its blacklisted extensions.
163 testing::AssertionResult IsInstalled(const Extension* extension) {
164 std::string id = extension->id();
165 if (!extension_service()->extensions()->Contains(id))
166 return testing::AssertionFailure() << id << " is not in extensions";
167 return IsInValidState(extension);
168 }
169
170 // Returns whether |extension| is strictly blacklisted: in ExtensionService's
171 // blacklist, and not installed.
172 testing::AssertionResult IsBlacklisted(const Extension* extension) {
173 std::string id = extension->id();
174 if (!extension_service()->blacklisted_extensions()->Contains(id))
175 return testing::AssertionFailure() << id << " is not in blacklisted";
176 return IsInValidState(extension);
177 }
178
179 std::set<std::string> GetTestExtensionIDs() {
180 std::set<std::string> extension_ids;
181 extension_ids.insert(info_a_.id());
182 extension_ids.insert(info_b_.id());
183 return extension_ids;
184 }
185
186 Profile* profile() {
asargent_no_longer_on_chrome 2012/11/30 21:44:22 optional suggestion: It might be worth hoisting th
not at google - send to devlin 2012/11/30 23:09:54 Done.
187 return browser()->profile();
188 }
189
190 ExtensionSystem* extension_system() {
191 return ExtensionSystem::Get(profile());
192 }
193
194 ExtensionService* extension_service() {
asargent_no_longer_on_chrome 2012/11/30 21:44:22 same for this one
not at google - send to devlin 2012/11/30 23:09:54 Done.
195 return extension_system()->extension_service();
196 }
197
198 CrxInfo info_a_;
199
200 CrxInfo info_b_;
201
202 private:
203 // Returns whether |extension| is either installed or blacklisted, but
204 // neither both nor neither.
205 testing::AssertionResult IsInValidState(const Extension* extension) {
206 std::string id = extension->id();
207 bool is_blacklisted =
208 extension_service()->blacklisted_extensions()->Contains(id);
209 bool is_installed = extension_service()->GetInstalledExtension(id);
210 if (is_blacklisted && is_installed) {
211 return testing::AssertionFailure() <<
212 id << " is both installed and in blacklisted_extensions";
213 }
214 if (!is_blacklisted && !is_installed) {
215 return testing::AssertionFailure() <<
216 id << " is neither installed nor in blacklisted_extensions";
217 }
218 return testing::AssertionSuccess();
219 }
220 };
221
222 // Stage 1: blacklisting when there weren't any extensions installed when the
223 // browser started.
224 IN_PROC_BROWSER_TEST_F(ExtensionBlacklistBrowserTest, PRE_Blacklist) {
225 //FilteringNotificationObserver notifications(
226 // content::Source<Profile>(profile()), GetTestExtensionIDs());
227 FilteringNotificationObserver notifications(
228 content::NotificationService::AllSources(), GetTestExtensionIDs());
229
230 scoped_refptr<const Extension> extension_a =
231 InstallExtension(test_data_dir_.AppendASCII(info_a_.path()), 1);
232 scoped_refptr<const Extension> extension_b =
233 InstallExtension(test_data_dir_.AppendASCII(info_b_.path()), 1);
234
235 EXPECT_TRUE(notifications.CheckNotifications(
236 chrome::NOTIFICATION_EXTENSION_INSTALLED,
237 chrome::NOTIFICATION_EXTENSION_LOADED,
238 chrome::NOTIFICATION_EXTENSION_INSTALLED,
239 chrome::NOTIFICATION_EXTENSION_LOADED));
240
241 ASSERT_TRUE(extension_a);
242 ASSERT_TRUE(extension_b);
243 ASSERT_EQ(info_a_.id(), extension_a->id());
244 ASSERT_EQ(info_b_.id(), extension_b->id());
245
246 std::vector<std::string> empty_vector;
247 std::vector<std::string> vector_a(1, info_a_.id());
248 std::vector<std::string> vector_b(1, info_b_.id());
249 std::vector<std::string> vector_ab(1, info_a_.id());
250 vector_ab.push_back(info_b_.id());
251
252 EXPECT_TRUE(IsInstalled(extension_a));
253 EXPECT_TRUE(IsInstalled(extension_b));
254
255 // Blacklist a.
256 extension_system()->blacklist()->SetFromUpdater(vector_a, "1");
257 base::RunLoop().RunUntilIdle();
258
259 EXPECT_TRUE(IsBlacklisted(extension_a));
260 EXPECT_TRUE(IsInstalled(extension_b));
261 EXPECT_TRUE(notifications.CheckNotifications(
262 chrome::NOTIFICATION_EXTENSION_UNLOADED));
263
264 // Un-blacklist a.
265 extension_system()->blacklist()->SetFromUpdater(empty_vector, "2");
266 base::RunLoop().RunUntilIdle();
267
268 EXPECT_TRUE(IsInstalled(extension_a));
269 EXPECT_TRUE(IsInstalled(extension_b));
270 EXPECT_TRUE(notifications.CheckNotifications(
271 chrome::NOTIFICATION_EXTENSION_LOADED));
272
273 // Blacklist a then switch with b.
274 extension_system()->blacklist()->SetFromUpdater(vector_a, "3");
275 base::RunLoop().RunUntilIdle();
276
277 EXPECT_TRUE(IsBlacklisted(extension_a));
278 EXPECT_TRUE(IsInstalled(extension_b));
279 EXPECT_TRUE(notifications.CheckNotifications(
280 chrome::NOTIFICATION_EXTENSION_UNLOADED));
281
282 extension_system()->blacklist()->SetFromUpdater(vector_b, "4");
283 base::RunLoop().RunUntilIdle();
284
285 EXPECT_TRUE(IsInstalled(extension_a));
286 EXPECT_TRUE(IsBlacklisted(extension_b));
287 EXPECT_TRUE(notifications.CheckNotifications(
288 chrome::NOTIFICATION_EXTENSION_LOADED,
289 chrome::NOTIFICATION_EXTENSION_UNLOADED));
290
291 // Add a to blacklist.
292 extension_system()->blacklist()->SetFromUpdater(vector_ab, "5");
293 base::RunLoop().RunUntilIdle();
294
295 EXPECT_TRUE(IsBlacklisted(extension_a));
296 EXPECT_TRUE(IsBlacklisted(extension_b));
297 EXPECT_TRUE(notifications.CheckNotifications(
298 chrome::NOTIFICATION_EXTENSION_UNLOADED));
299
300 // Clear blacklist.
301 extension_system()->blacklist()->SetFromUpdater(empty_vector, "6");
302 base::RunLoop().RunUntilIdle();
303
304 EXPECT_TRUE(IsInstalled(extension_a));
305 EXPECT_TRUE(IsInstalled(extension_b));
306 EXPECT_TRUE(notifications.CheckNotifications(
307 chrome::NOTIFICATION_EXTENSION_LOADED,
308 chrome::NOTIFICATION_EXTENSION_LOADED));
309
310 // Add b back again for the next test.
311 extension_system()->blacklist()->SetFromUpdater(vector_b, "7");
312 base::RunLoop().RunUntilIdle();
313
314 EXPECT_TRUE(IsInstalled(extension_a));
315 EXPECT_TRUE(IsBlacklisted(extension_b));
316 EXPECT_TRUE(notifications.CheckNotifications(
317 chrome::NOTIFICATION_EXTENSION_UNLOADED));
318 }
319
320 // Stage 2: blacklisting with extensions A and B having been installed,
321 // with B actually in the blacklist.
322 IN_PROC_BROWSER_TEST_F(ExtensionBlacklistBrowserTest, Blacklist) {
323 FilteringNotificationObserver notifications(
324 content::Source<Profile>(profile()), GetTestExtensionIDs());
325
326 scoped_refptr<const Extension> extension_a =
327 extension_service()->extensions()->GetByID(info_a_.id());
328 ASSERT_TRUE(extension_a);
329
330 scoped_refptr<const Extension> extension_b =
331 extension_service()->blacklisted_extensions()->GetByID(info_b_.id());
332 ASSERT_TRUE(extension_b);
333
334 EXPECT_TRUE(IsInstalled(extension_a));
335 EXPECT_TRUE(IsBlacklisted(extension_b));
336
337 // Make sure that we can still blacklist a and unblacklist b.
338 std::vector<std::string> vector_a(1, extension_a->id());
339 extension_system()->blacklist()->SetFromUpdater(vector_a, "8");
340 base::RunLoop().RunUntilIdle();
341
342 EXPECT_TRUE(IsBlacklisted(extension_a));
343 EXPECT_TRUE(IsInstalled(extension_b));
344 EXPECT_TRUE(notifications.CheckNotifications(
345 chrome::NOTIFICATION_EXTENSION_LOADED,
346 chrome::NOTIFICATION_EXTENSION_UNLOADED));
347 }
348
349 } // namespace extensions
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698