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

Unified 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, 1 month 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 side-by-side diff with in-line comments
Download patch
Index: chrome/browser/extensions/extension_blacklist_browsertest.cc
diff --git a/chrome/browser/extensions/extension_blacklist_browsertest.cc b/chrome/browser/extensions/extension_blacklist_browsertest.cc
new file mode 100644
index 0000000000000000000000000000000000000000..53cc3e3cf3c8c0a1678827973e8154cc45e1edf8
--- /dev/null
+++ b/chrome/browser/extensions/extension_blacklist_browsertest.cc
@@ -0,0 +1,349 @@
+// Copyright 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "base/run_loop.h"
+#include "base/stringprintf.h"
+#include "chrome/browser/extensions/blacklist.h"
+#include "chrome/browser/extensions/extension_browsertest.h"
+#include "chrome/browser/extensions/extension_service.h"
+#include "chrome/browser/extensions/extension_system.h"
+#include "chrome/browser/ui/browser.h"
+#include "chrome/common/chrome_notification_types.h"
+#include "chrome/common/extensions/extension.h"
+#include "chrome/common/extensions/extension_constants.h"
+#include "content/public/browser/notification_details.h"
+#include "content/public/browser/notification_observer.h"
+#include "content/public/browser/notification_registrar.h"
+#include "content/public/browser/notification_source.h"
+
+namespace extensions {
+
+namespace {
+
+// Records notifications, but only for extensions with specific IDs.
+class FilteringNotificationObserver : public content::NotificationObserver {
+ public:
+ FilteringNotificationObserver(
+ content::NotificationSource source,
+ const std::set<std::string>& extension_ids)
+ : extension_ids_(extension_ids) {
+ registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_LOADED, source);
+ registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_INSTALLED, source);
+ registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_UNLOADED, source);
+ }
+
+ // Checks then clears notifications for our extensions.
+ testing::AssertionResult CheckNotifications(chrome::NotificationType type) {
+ return CheckNotifications(std::vector<chrome::NotificationType>(1, type));
+ }
+
+ // Checks then clears notifications for our extensions.
+ testing::AssertionResult CheckNotifications(chrome::NotificationType t1,
+ chrome::NotificationType t2) {
+ std::vector<chrome::NotificationType> types;
+ types.push_back(t1);
+ types.push_back(t2);
+ return CheckNotifications(types);
+ }
+
+ // Checks then clears notifications for our extensions.
+ testing::AssertionResult CheckNotifications(chrome::NotificationType t1,
+ chrome::NotificationType t2,
+ chrome::NotificationType t3,
+ chrome::NotificationType t4) {
+ std::vector<chrome::NotificationType> types;
+ types.push_back(t1);
+ types.push_back(t2);
+ types.push_back(t3);
+ types.push_back(t4);
+ return CheckNotifications(types);
+ }
+
+ private:
+ // content::NotificationObserver implementation.
+ virtual void Observe(int type,
+ const content::NotificationSource& source,
+ const content::NotificationDetails& details) OVERRIDE {
+ switch (type) {
+ case chrome::NOTIFICATION_EXTENSION_INSTALLED: {
+ const Extension* extension =
+ content::Details<const Extension>(details).ptr();
+ if (extension_ids_.count(extension->id()))
+ notifications_.push_back(static_cast<chrome::NotificationType>(type));
+ break;
+ }
+
+ case chrome::NOTIFICATION_EXTENSION_LOADED: {
+ const Extension* extension =
+ content::Details<const Extension>(details).ptr();
+ if (extension_ids_.count(extension->id()))
+ notifications_.push_back(static_cast<chrome::NotificationType>(type));
+ break;
+ }
+
+ case chrome::NOTIFICATION_EXTENSION_UNLOADED: {
+ UnloadedExtensionInfo* reason =
+ content::Details<UnloadedExtensionInfo>(details).ptr();
+ if (extension_ids_.count(reason->extension->id())) {
+ notifications_.push_back(static_cast<chrome::NotificationType>(type));
+ // The only way that extensions are unloaded in these tests is
+ // by blacklisting.
+ EXPECT_EQ(extension_misc::UNLOAD_REASON_BLACKLIST,
+ reason->reason);
+ }
+ break;
+ }
+
+ default:
+ NOTREACHED();
+ break;
+ }
+ }
+
+ // Checks then clears notifications for our extensions.
+ testing::AssertionResult CheckNotifications(
+ const std::vector<chrome::NotificationType>& types) {
+ testing::AssertionResult result = (notifications_ == types) ?
+ testing::AssertionSuccess() :
+ testing::AssertionFailure() << "Expected " << Str(types) << ", " <<
+ "Got " << Str(notifications_);
+ notifications_.clear();
+ return result;
+ }
+
+ std::string Str(const std::vector<chrome::NotificationType>& types) {
+ std::string str = "[";
+ bool needs_comma = false;
+ for (std::vector<chrome::NotificationType>::const_iterator it =
+ types.begin(); it != types.end(); ++it) {
+ if (needs_comma)
+ str += ",";
+ needs_comma = true;
+ str += base::StringPrintf("%d", *it);
+ }
+ return str + "]";
+ }
+
+ const std::set<std::string> extension_ids_;
+
+ std::vector<chrome::NotificationType> notifications_;
+
+ content::NotificationRegistrar registrar_;
+};
+
+// Stores the paths to CRX files of extensions, and the extension's ID.
+// Use arbitrary extensions; we're just testing blacklisting behavior.
+class CrxInfo {
+ public:
+ CrxInfo(const std::string& path, const std::string& id)
+ : path_(path), id_(id) {}
+
+ const std::string& path() { return path_; }
+ const std::string& id() { return id_; }
+
+ private:
+ const std::string path_;
+ const std::string id_;
+};
+
+} // namespace
+
+class ExtensionBlacklistBrowserTest : public ExtensionBrowserTest {
+ public:
+ ExtensionBlacklistBrowserTest()
+ : info_a_("install/install.crx", "ogdbpbegnmindpdjfafpmpicikegejdj"),
+ info_b_("autoupdate/v1.crx", "ogjcoiohnmldgjemafoockdghcjciccf") {}
+
+ virtual ~ExtensionBlacklistBrowserTest() {}
+
+ protected:
+ // Returns whether |extension| is strictly installed: in ExtensionService's
+ // installed extensions, and not in its blacklisted extensions.
+ testing::AssertionResult IsInstalled(const Extension* extension) {
+ std::string id = extension->id();
+ if (!extension_service()->extensions()->Contains(id))
+ return testing::AssertionFailure() << id << " is not in extensions";
+ return IsInValidState(extension);
+ }
+
+ // Returns whether |extension| is strictly blacklisted: in ExtensionService's
+ // blacklist, and not installed.
+ testing::AssertionResult IsBlacklisted(const Extension* extension) {
+ std::string id = extension->id();
+ if (!extension_service()->blacklisted_extensions()->Contains(id))
+ return testing::AssertionFailure() << id << " is not in blacklisted";
+ return IsInValidState(extension);
+ }
+
+ std::set<std::string> GetTestExtensionIDs() {
+ std::set<std::string> extension_ids;
+ extension_ids.insert(info_a_.id());
+ extension_ids.insert(info_b_.id());
+ return extension_ids;
+ }
+
+ 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.
+ return browser()->profile();
+ }
+
+ ExtensionSystem* extension_system() {
+ return ExtensionSystem::Get(profile());
+ }
+
+ 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.
+ return extension_system()->extension_service();
+ }
+
+ CrxInfo info_a_;
+
+ CrxInfo info_b_;
+
+ private:
+ // Returns whether |extension| is either installed or blacklisted, but
+ // neither both nor neither.
+ testing::AssertionResult IsInValidState(const Extension* extension) {
+ std::string id = extension->id();
+ bool is_blacklisted =
+ extension_service()->blacklisted_extensions()->Contains(id);
+ bool is_installed = extension_service()->GetInstalledExtension(id);
+ if (is_blacklisted && is_installed) {
+ return testing::AssertionFailure() <<
+ id << " is both installed and in blacklisted_extensions";
+ }
+ if (!is_blacklisted && !is_installed) {
+ return testing::AssertionFailure() <<
+ id << " is neither installed nor in blacklisted_extensions";
+ }
+ return testing::AssertionSuccess();
+ }
+};
+
+// Stage 1: blacklisting when there weren't any extensions installed when the
+// browser started.
+IN_PROC_BROWSER_TEST_F(ExtensionBlacklistBrowserTest, PRE_Blacklist) {
+ //FilteringNotificationObserver notifications(
+ // content::Source<Profile>(profile()), GetTestExtensionIDs());
+ FilteringNotificationObserver notifications(
+ content::NotificationService::AllSources(), GetTestExtensionIDs());
+
+ scoped_refptr<const Extension> extension_a =
+ InstallExtension(test_data_dir_.AppendASCII(info_a_.path()), 1);
+ scoped_refptr<const Extension> extension_b =
+ InstallExtension(test_data_dir_.AppendASCII(info_b_.path()), 1);
+
+ EXPECT_TRUE(notifications.CheckNotifications(
+ chrome::NOTIFICATION_EXTENSION_INSTALLED,
+ chrome::NOTIFICATION_EXTENSION_LOADED,
+ chrome::NOTIFICATION_EXTENSION_INSTALLED,
+ chrome::NOTIFICATION_EXTENSION_LOADED));
+
+ ASSERT_TRUE(extension_a);
+ ASSERT_TRUE(extension_b);
+ ASSERT_EQ(info_a_.id(), extension_a->id());
+ ASSERT_EQ(info_b_.id(), extension_b->id());
+
+ std::vector<std::string> empty_vector;
+ std::vector<std::string> vector_a(1, info_a_.id());
+ std::vector<std::string> vector_b(1, info_b_.id());
+ std::vector<std::string> vector_ab(1, info_a_.id());
+ vector_ab.push_back(info_b_.id());
+
+ EXPECT_TRUE(IsInstalled(extension_a));
+ EXPECT_TRUE(IsInstalled(extension_b));
+
+ // Blacklist a.
+ extension_system()->blacklist()->SetFromUpdater(vector_a, "1");
+ base::RunLoop().RunUntilIdle();
+
+ EXPECT_TRUE(IsBlacklisted(extension_a));
+ EXPECT_TRUE(IsInstalled(extension_b));
+ EXPECT_TRUE(notifications.CheckNotifications(
+ chrome::NOTIFICATION_EXTENSION_UNLOADED));
+
+ // Un-blacklist a.
+ extension_system()->blacklist()->SetFromUpdater(empty_vector, "2");
+ base::RunLoop().RunUntilIdle();
+
+ EXPECT_TRUE(IsInstalled(extension_a));
+ EXPECT_TRUE(IsInstalled(extension_b));
+ EXPECT_TRUE(notifications.CheckNotifications(
+ chrome::NOTIFICATION_EXTENSION_LOADED));
+
+ // Blacklist a then switch with b.
+ extension_system()->blacklist()->SetFromUpdater(vector_a, "3");
+ base::RunLoop().RunUntilIdle();
+
+ EXPECT_TRUE(IsBlacklisted(extension_a));
+ EXPECT_TRUE(IsInstalled(extension_b));
+ EXPECT_TRUE(notifications.CheckNotifications(
+ chrome::NOTIFICATION_EXTENSION_UNLOADED));
+
+ extension_system()->blacklist()->SetFromUpdater(vector_b, "4");
+ base::RunLoop().RunUntilIdle();
+
+ EXPECT_TRUE(IsInstalled(extension_a));
+ EXPECT_TRUE(IsBlacklisted(extension_b));
+ EXPECT_TRUE(notifications.CheckNotifications(
+ chrome::NOTIFICATION_EXTENSION_LOADED,
+ chrome::NOTIFICATION_EXTENSION_UNLOADED));
+
+ // Add a to blacklist.
+ extension_system()->blacklist()->SetFromUpdater(vector_ab, "5");
+ base::RunLoop().RunUntilIdle();
+
+ EXPECT_TRUE(IsBlacklisted(extension_a));
+ EXPECT_TRUE(IsBlacklisted(extension_b));
+ EXPECT_TRUE(notifications.CheckNotifications(
+ chrome::NOTIFICATION_EXTENSION_UNLOADED));
+
+ // Clear blacklist.
+ extension_system()->blacklist()->SetFromUpdater(empty_vector, "6");
+ base::RunLoop().RunUntilIdle();
+
+ EXPECT_TRUE(IsInstalled(extension_a));
+ EXPECT_TRUE(IsInstalled(extension_b));
+ EXPECT_TRUE(notifications.CheckNotifications(
+ chrome::NOTIFICATION_EXTENSION_LOADED,
+ chrome::NOTIFICATION_EXTENSION_LOADED));
+
+ // Add b back again for the next test.
+ extension_system()->blacklist()->SetFromUpdater(vector_b, "7");
+ base::RunLoop().RunUntilIdle();
+
+ EXPECT_TRUE(IsInstalled(extension_a));
+ EXPECT_TRUE(IsBlacklisted(extension_b));
+ EXPECT_TRUE(notifications.CheckNotifications(
+ chrome::NOTIFICATION_EXTENSION_UNLOADED));
+}
+
+// Stage 2: blacklisting with extensions A and B having been installed,
+// with B actually in the blacklist.
+IN_PROC_BROWSER_TEST_F(ExtensionBlacklistBrowserTest, Blacklist) {
+ FilteringNotificationObserver notifications(
+ content::Source<Profile>(profile()), GetTestExtensionIDs());
+
+ scoped_refptr<const Extension> extension_a =
+ extension_service()->extensions()->GetByID(info_a_.id());
+ ASSERT_TRUE(extension_a);
+
+ scoped_refptr<const Extension> extension_b =
+ extension_service()->blacklisted_extensions()->GetByID(info_b_.id());
+ ASSERT_TRUE(extension_b);
+
+ EXPECT_TRUE(IsInstalled(extension_a));
+ EXPECT_TRUE(IsBlacklisted(extension_b));
+
+ // Make sure that we can still blacklist a and unblacklist b.
+ std::vector<std::string> vector_a(1, extension_a->id());
+ extension_system()->blacklist()->SetFromUpdater(vector_a, "8");
+ base::RunLoop().RunUntilIdle();
+
+ EXPECT_TRUE(IsBlacklisted(extension_a));
+ EXPECT_TRUE(IsInstalled(extension_b));
+ EXPECT_TRUE(notifications.CheckNotifications(
+ chrome::NOTIFICATION_EXTENSION_LOADED,
+ chrome::NOTIFICATION_EXTENSION_UNLOADED));
+}
+
+} // namespace extensions

Powered by Google App Engine
This is Rietveld 408576698