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

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: fix another test 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 std::vector<chrome::NotificationType> types;
55 types.push_back(t1);
56 types.push_back(t2);
57 types.push_back(t3);
58 return CheckNotifications(types);
59 }
60
61 // Checks then clears notifications for our extensions.
62 testing::AssertionResult CheckNotifications(chrome::NotificationType t1,
63 chrome::NotificationType t2,
64 chrome::NotificationType t3,
65 chrome::NotificationType t4,
66 chrome::NotificationType t5,
67 chrome::NotificationType t6) {
68 std::vector<chrome::NotificationType> types;
69 types.push_back(t1);
70 types.push_back(t2);
71 types.push_back(t3);
72 types.push_back(t4);
73 types.push_back(t5);
74 types.push_back(t6);
75 return CheckNotifications(types);
76 }
77
78 private:
79 // content::NotificationObserver implementation.
80 virtual void Observe(int type,
81 const content::NotificationSource& source,
82 const content::NotificationDetails& details) OVERRIDE {
83 switch (type) {
84 case chrome::NOTIFICATION_EXTENSION_INSTALLED: {
85 const Extension* extension =
86 content::Details<const Extension>(details).ptr();
87 if (extension_ids_.count(extension->id()))
88 notifications_.push_back(static_cast<chrome::NotificationType>(type));
89 break;
90 }
91
92 case chrome::NOTIFICATION_EXTENSION_LOADED: {
93 const Extension* extension =
94 content::Details<const Extension>(details).ptr();
95 if (extension_ids_.count(extension->id()))
96 notifications_.push_back(static_cast<chrome::NotificationType>(type));
97 break;
98 }
99
100 case chrome::NOTIFICATION_EXTENSION_UNLOADED: {
101 UnloadedExtensionInfo* reason =
102 content::Details<UnloadedExtensionInfo>(details).ptr();
103 if (extension_ids_.count(reason->extension->id())) {
104 notifications_.push_back(static_cast<chrome::NotificationType>(type));
105 // The only way that extensions are unloaded in these tests is
106 // by blacklisting.
107 EXPECT_EQ(extension_misc::UNLOAD_REASON_BLACKLIST,
108 reason->reason);
109 }
110 break;
111 }
112
113 default:
114 NOTREACHED();
115 break;
116 }
117 }
118
119 // Checks then clears notifications for our extensions.
120 testing::AssertionResult CheckNotifications(
121 const std::vector<chrome::NotificationType>& types) {
122 testing::AssertionResult result = (notifications_ == types) ?
123 testing::AssertionSuccess() :
124 testing::AssertionFailure() << "Expected " << Str(types) << ", " <<
125 "Got " << Str(notifications_);
126 notifications_.clear();
127 return result;
128 }
129
130 std::string Str(const std::vector<chrome::NotificationType>& types) {
131 std::string str = "[";
132 bool needs_comma = false;
133 for (std::vector<chrome::NotificationType>::const_iterator it =
134 types.begin(); it != types.end(); ++it) {
135 if (needs_comma)
136 str += ",";
137 needs_comma = true;
138 str += base::StringPrintf("%d", *it);
139 }
140 return str + "]";
141 }
142
143 const std::set<std::string> extension_ids_;
144
145 std::vector<chrome::NotificationType> notifications_;
146
147 content::NotificationRegistrar registrar_;
148 };
149
150 // Stores the paths to CRX files of extensions, and the extension's ID.
151 // Use arbitrary extensions; we're just testing blacklisting behavior.
152 class CrxInfo {
153 public:
154 CrxInfo(const std::string& path, const std::string& id)
155 : path_(path), id_(id) {}
156
157 const std::string& path() { return path_; }
158 const std::string& id() { return id_; }
159
160 private:
161 const std::string path_;
162 const std::string id_;
163 };
164
165 } // namespace
166
167 class ExtensionBlacklistBrowserTest : public ExtensionBrowserTest {
168 public:
169 ExtensionBlacklistBrowserTest()
170 : info_a_("install/install.crx", "ogdbpbegnmindpdjfafpmpicikegejdj"),
171 info_b_("autoupdate/v1.crx", "ogjcoiohnmldgjemafoockdghcjciccf"),
172 info_c_("hosted_app.crx", "kbmnembihfiondgfjekmnmcbddelicoi") {}
173
174 virtual ~ExtensionBlacklistBrowserTest() {}
175
176 protected:
177 // Returns whether |extension| is strictly safe: in one of ExtensionService's
178 // non-blacklisted extension sets, and not in its blacklisted extensions.
179 testing::AssertionResult IsSafe(const Extension* extension) {
180 std::string id = extension->id();
181 int include_mask = ExtensionService::INCLUDE_EVERYTHING &
182 ~ExtensionService::INCLUDE_BLACKLISTED;
183 if (!extension_service()->GetExtensionById(id, include_mask))
184 return testing::AssertionFailure() << id << " is safe";
185 return IsInValidState(extension);
186 }
187
188 // Returns whether |extension| is strictly blacklisted: in ExtensionService's
189 // blacklist, and not in any of its other extension sets.
190 testing::AssertionResult IsBlacklisted(const Extension* extension) {
191 std::string id = extension->id();
192 if (!extension_service()->blacklisted_extensions()->Contains(id))
193 return testing::AssertionFailure() << id << " is not blacklisted";
194 return IsInValidState(extension);
195 }
196
197 std::set<std::string> GetTestExtensionIDs() {
198 std::set<std::string> extension_ids;
199 extension_ids.insert(info_a_.id());
200 extension_ids.insert(info_b_.id());
201 extension_ids.insert(info_c_.id());
202 return extension_ids;
203 }
204
205 Blacklist* blacklist() {
206 return ExtensionSystem::Get(profile())->blacklist();
207 }
208
209 CrxInfo info_a_;
210 CrxInfo info_b_;
211 CrxInfo info_c_;
212
213 private:
214 // Returns whether |extension| is either installed or blacklisted, but
215 // neither both nor neither.
216 testing::AssertionResult IsInValidState(const Extension* extension) {
217 std::string id = extension->id();
218 bool is_blacklisted =
219 extension_service()->blacklisted_extensions()->Contains(id);
220 int safe_mask = ExtensionService::INCLUDE_EVERYTHING &
221 ~ExtensionService::INCLUDE_BLACKLISTED;
222 bool is_safe = extension_service()->GetExtensionById(id, safe_mask) != NULL;
223 if (is_blacklisted && is_safe) {
224 return testing::AssertionFailure() <<
225 id << " is both safe and in blacklisted_extensions";
226 }
227 if (!is_blacklisted && !is_safe) {
228 return testing::AssertionFailure() <<
229 id << " is neither safe nor in blacklisted_extensions";
230 }
231 return testing::AssertionSuccess();
232 }
233 };
234
235 // Stage 1: blacklisting when there weren't any extensions installed when the
236 // browser started.
237 IN_PROC_BROWSER_TEST_F(ExtensionBlacklistBrowserTest, PRE_Blacklist) {
238 FilteringNotificationObserver notifications(
239 content::NotificationService::AllSources(), GetTestExtensionIDs());
240
241 scoped_refptr<const Extension> extension_a =
242 InstallExtension(test_data_dir_.AppendASCII(info_a_.path()), 1);
243 scoped_refptr<const Extension> extension_b =
244 InstallExtension(test_data_dir_.AppendASCII(info_b_.path()), 1);
245 scoped_refptr<const Extension> extension_c =
246 InstallExtension(test_data_dir_.AppendASCII(info_c_.path()), 1);
247
248 EXPECT_TRUE(notifications.CheckNotifications(
249 chrome::NOTIFICATION_EXTENSION_INSTALLED,
250 chrome::NOTIFICATION_EXTENSION_LOADED,
251 chrome::NOTIFICATION_EXTENSION_INSTALLED,
252 chrome::NOTIFICATION_EXTENSION_LOADED,
253 chrome::NOTIFICATION_EXTENSION_INSTALLED,
254 chrome::NOTIFICATION_EXTENSION_LOADED));
255
256 ASSERT_TRUE(extension_a);
257 ASSERT_TRUE(extension_b);
258 ASSERT_EQ(info_a_.id(), extension_a->id());
259 ASSERT_EQ(info_b_.id(), extension_b->id());
260 ASSERT_EQ(info_c_.id(), extension_c->id());
261
262 std::vector<std::string> empty_vector;
263 std::vector<std::string> vector_a(1, info_a_.id());
264 std::vector<std::string> vector_b(1, info_b_.id());
265 std::vector<std::string> vector_c(1, info_c_.id());
266 std::vector<std::string> vector_ab(1, info_a_.id());
267 vector_ab.push_back(info_b_.id());
268 std::vector<std::string> vector_bc(1, info_b_.id());
269 vector_bc.push_back(info_c_.id());
270 std::vector<std::string> vector_abc(1, info_a_.id());
271 vector_abc.push_back(info_b_.id());
272 vector_abc.push_back(info_c_.id());
273
274 EXPECT_TRUE(IsSafe(extension_a));
275 EXPECT_TRUE(IsSafe(extension_b));
276 EXPECT_TRUE(IsSafe(extension_c));
277
278 // Blacklist a and b.
279 blacklist()->SetFromUpdater(vector_ab, "1");
280 base::RunLoop().RunUntilIdle();
281
282 EXPECT_TRUE(IsBlacklisted(extension_a));
283 EXPECT_TRUE(IsBlacklisted(extension_b));
284 EXPECT_TRUE(IsSafe(extension_c));
285 EXPECT_TRUE(notifications.CheckNotifications(
286 chrome::NOTIFICATION_EXTENSION_UNLOADED,
287 chrome::NOTIFICATION_EXTENSION_UNLOADED));
288
289 // Un-blacklist a.
290 blacklist()->SetFromUpdater(vector_b, "2");
291 base::RunLoop().RunUntilIdle();
292
293 EXPECT_TRUE(IsSafe(extension_a));
294 EXPECT_TRUE(IsBlacklisted(extension_b));
295 EXPECT_TRUE(IsSafe(extension_c));
296 EXPECT_TRUE(notifications.CheckNotifications(
297 chrome::NOTIFICATION_EXTENSION_LOADED));
298
299 // Blacklist a then switch with c.
300 blacklist()->SetFromUpdater(vector_ab, "3");
301 base::RunLoop().RunUntilIdle();
302
303 EXPECT_TRUE(IsBlacklisted(extension_a));
304 EXPECT_TRUE(IsBlacklisted(extension_b));
305 EXPECT_TRUE(IsSafe(extension_c));
306 EXPECT_TRUE(notifications.CheckNotifications(
307 chrome::NOTIFICATION_EXTENSION_UNLOADED));
308
309 blacklist()->SetFromUpdater(vector_bc, "4");
310 base::RunLoop().RunUntilIdle();
311
312 EXPECT_TRUE(IsSafe(extension_a));
313 EXPECT_TRUE(IsBlacklisted(extension_b));
314 EXPECT_TRUE(IsBlacklisted(extension_c));
315 EXPECT_TRUE(notifications.CheckNotifications(
316 chrome::NOTIFICATION_EXTENSION_LOADED,
317 chrome::NOTIFICATION_EXTENSION_UNLOADED));
318
319 // Add a to blacklist.
320 blacklist()->SetFromUpdater(vector_abc, "5");
321 base::RunLoop().RunUntilIdle();
322
323 EXPECT_TRUE(IsBlacklisted(extension_a));
324 EXPECT_TRUE(IsBlacklisted(extension_b));
325 EXPECT_TRUE(IsBlacklisted(extension_c));
326 EXPECT_TRUE(notifications.CheckNotifications(
327 chrome::NOTIFICATION_EXTENSION_UNLOADED));
328
329 // Clear blacklist.
330 blacklist()->SetFromUpdater(empty_vector, "6");
331 base::RunLoop().RunUntilIdle();
332
333 EXPECT_TRUE(IsSafe(extension_a));
334 EXPECT_TRUE(IsSafe(extension_b));
335 EXPECT_TRUE(IsSafe(extension_c));
336 EXPECT_TRUE(notifications.CheckNotifications(
337 chrome::NOTIFICATION_EXTENSION_LOADED,
338 chrome::NOTIFICATION_EXTENSION_LOADED,
339 chrome::NOTIFICATION_EXTENSION_LOADED));
340
341 // Add a and b back again for the next test.
342 blacklist()->SetFromUpdater(vector_ab, "7");
343 base::RunLoop().RunUntilIdle();
344
345 EXPECT_TRUE(IsBlacklisted(extension_a));
346 EXPECT_TRUE(IsBlacklisted(extension_b));
347 EXPECT_TRUE(IsSafe(extension_c));
348 EXPECT_TRUE(notifications.CheckNotifications(
349 chrome::NOTIFICATION_EXTENSION_UNLOADED,
350 chrome::NOTIFICATION_EXTENSION_UNLOADED));
351 }
352
353 // Stage 2: blacklisting with extensions A and B having been installed,
354 // with A actually in the blacklist.
355 IN_PROC_BROWSER_TEST_F(ExtensionBlacklistBrowserTest, Blacklist) {
356 FilteringNotificationObserver notifications(
357 content::Source<Profile>(profile()), GetTestExtensionIDs());
358
359 scoped_refptr<const Extension> extension_a =
360 extension_service()->blacklisted_extensions()->GetByID(info_a_.id());
361 ASSERT_TRUE(extension_a);
362
363 scoped_refptr<const Extension> extension_b =
364 extension_service()->blacklisted_extensions()->GetByID(info_b_.id());
365 ASSERT_TRUE(extension_b);
366
367 scoped_refptr<const Extension> extension_c =
368 extension_service()->extensions()->GetByID(info_c_.id());
369 ASSERT_TRUE(extension_c);
370
371 EXPECT_TRUE(IsBlacklisted(extension_a));
372 EXPECT_TRUE(IsBlacklisted(extension_b));
373 EXPECT_TRUE(IsSafe(extension_c));
374
375 // Make sure that we can still blacklist c and unblacklist b.
376 std::vector<std::string> vector_ac(1, extension_a->id());
377 vector_ac.push_back(extension_c->id());
378 blacklist()->SetFromUpdater(vector_ac, "8");
379 base::RunLoop().RunUntilIdle();
380
381 EXPECT_TRUE(IsBlacklisted(extension_a));
382 EXPECT_TRUE(IsSafe(extension_b));
383 EXPECT_TRUE(IsBlacklisted(extension_c));
384 EXPECT_TRUE(notifications.CheckNotifications(
385 chrome::NOTIFICATION_EXTENSION_LOADED,
386 chrome::NOTIFICATION_EXTENSION_UNLOADED));
387 }
388
389 } // namespace extensions
OLDNEW
« no previous file with comments | « chrome/browser/extensions/blacklist_unittest.cc ('k') | chrome/browser/extensions/extension_browsertest.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698