Bug 982101 - Test automatically activating plugins that are bundled inside of extensions. r=bsmedberg
authorGeorg Fritzsche <georg.fritzsche@googlemail.com>
Sat, 19 Apr 2014 14:17:19 +0200
changeset 197851 6022ca67befb0d749024085dd2678728565b38fb
parent 197850 46b65a3ccf6f0d2c61e6706d3767a224de10de06
child 197852 7e51adede3b6b78c19c755fe08a1b177745e979c
push id3624
push userasasaki@mozilla.com
push dateMon, 09 Jun 2014 21:49:01 +0000
treeherdermozilla-beta@b1a5da15899a [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbsmedberg
bugs982101
milestone31.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 982101 - Test automatically activating plugins that are bundled inside of extensions. r=bsmedberg
dom/plugins/test/moz.build
dom/plugins/test/testaddon/Makefile.in
dom/plugins/test/testaddon/install.rdf
dom/plugins/test/testaddon/moz.build
dom/plugins/test/unit/head_plugins.js
dom/plugins/test/unit/test_plugin_default_state_xpi.js
dom/plugins/test/unit/xpcshell.ini
--- a/dom/plugins/test/moz.build
+++ b/dom/plugins/test/moz.build
@@ -1,14 +1,14 @@
 # -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
 # vim: set filetype=python:
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
-DIRS += ['testplugin']
+DIRS += ['testplugin', 'testaddon']
 
 XPCSHELL_TESTS_MANIFESTS += ['unit/xpcshell.ini']
 
 if CONFIG['MOZ_WIDGET_TOOLKIT'] in ('gtk2', 'gtk3', 'cocoa', 'windows'):
     MOCHITEST_MANIFESTS += ['mochitest/mochitest.ini']
     MOCHITEST_CHROME_MANIFESTS += ['mochitest/chrome.ini']
 
new file mode 100644
--- /dev/null
+++ b/dom/plugins/test/testaddon/Makefile.in
@@ -0,0 +1,23 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+include $(topsrcdir)/config/rules.mk
+
+ifeq ($(MOZ_WIDGET_TOOLKIT),cocoa)
+plugin_file_name = Test.plugin
+addon_file_name = testaddon_$(TARGET_XPCOM_ABI).xpi
+else
+plugin_file_name = $(DLL_PREFIX)nptest$(DLL_SUFFIX)
+addon_file_name = testaddon.xpi
+endif
+
+# This is so hacky. Waiting on bug 988938.
+testdir = $(abspath $(DEPTH)/_tests/xpcshell/dom/plugins/test/unit/)
+addonpath = $(testdir)/$(addon_file_name)
+
+libs::
+	$(NSINSTALL) -D $(testdir)
+	rm -f $(addonpath)
+	cd $(srcdir) && zip -rD $(addonpath) install.rdf
+	cd $(DIST) && zip -rD $(addonpath) plugins/$(plugin_file_name)
new file mode 100644
--- /dev/null
+++ b/dom/plugins/test/testaddon/install.rdf
@@ -0,0 +1,23 @@
+<?xml version="1.0"?>
+
+<RDF xmlns="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+     xmlns:em="http://www.mozilla.org/2004/em-rdf#">
+
+  <Description about="urn:mozilla:install-manifest">
+    <em:id>test-plugin-from-xpi@tests.mozilla.org</em:id>
+    <em:version>1</em:version>
+    <em:name>Test plugin from XPI</em:name>
+    <em:description>This tests shipping a plugin through an extensions.</em:description>
+
+    <em:targetApplication>
+      <Description>
+        <em:id>toolkit@mozilla.org</em:id>
+        <em:minVersion>0</em:minVersion>
+        <em:maxVersion>*</em:maxVersion>
+      </Description>
+    </em:targetApplication>
+
+    <em:unpack>true</em:unpack>
+
+  </Description>
+</RDF>
new file mode 100644
--- /dev/null
+++ b/dom/plugins/test/testaddon/moz.build
@@ -0,0 +1,5 @@
+# -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
+# vim: set filetype=python:
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
--- a/dom/plugins/test/unit/head_plugins.js
+++ b/dom/plugins/test/unit/head_plugins.js
@@ -1,20 +1,22 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
  */
 
-const Cc = Components.classes;
-const Ci = Components.interfaces;
+const {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components;
+
+Cu.import("resource://gre/modules/Promise.jsm");
 
 const gIsWindows = ("@mozilla.org/windows-registry-key;1" in Cc);
 const gIsOSX = ("nsILocalFileMac" in Ci);
 const gIsLinux = ("@mozilla.org/gnome-gconf-service;1" in Cc) ||
   ("@mozilla.org/gio-service;1" in Cc);
+const gDirSvc = Cc["@mozilla.org/file/directory_service;1"].getService(Ci.nsIProperties);
 
 // Finds the test plugin library
 function get_test_plugin() {
   var pluginEnum = gDirSvc.get("APluginsDL", Ci.nsISimpleEnumerator);
   while (pluginEnum.hasMoreElements()) {
     let dir = pluginEnum.getNext().QueryInterface(Ci.nsILocalFile);
     let plugin = dir.clone();
     // OSX plugin
@@ -37,17 +39,17 @@ function get_test_plugin() {
       plugin.normalize();
       return plugin;
     }
   }
   return null;
 }
 
 // Finds the test nsIPluginTag
-function get_test_plugintag(aName) {
+function get_test_plugintag(aName="Test Plug-in") {
   const Cc = Components.classes;
   const Ci = Components.interfaces;
 
   var name = aName || "Test Plug-in";
   var host = Cc["@mozilla.org/plugin/host;1"].
              getService(Ci.nsIPluginHost);
   var tags = host.getPluginTags();
 
@@ -114,8 +116,84 @@ function get_test_plugin_no_symlink() {
     let plugin = dir.clone();
     plugin.append(get_platform_specific_plugin_name());
     if (plugin.exists()) {
       return plugin;
     }
   }
   return null;
 }
+
+let gGlobalScope = this;
+function loadAddonManager() {
+  let ns = {};
+  Cu.import("resource://gre/modules/Services.jsm", ns);
+  let head = "../../../../toolkit/mozapps/extensions/test/xpcshell/head_addons.js";
+  let file = do_get_file(head);
+  let uri = ns.Services.io.newFileURI(file);
+  ns.Services.scriptloader.loadSubScript(uri.spec, gGlobalScope);
+  createAppInfo("xpcshell@tests.mozilla.org", "XPCShell", "1", "1.9.2");
+  startupManager();
+}
+
+// Install addon and return a Promise<boolean> that is
+// resolve with true on success, false otherwise.
+function installAddon(relativePath) {
+  let deferred = Promise.defer();
+  let success = () => deferred.resolve(true);
+  let fail = () => deferred.resolve(false);
+  let listener = {
+    onDownloadCancelled: fail,
+    onDownloadFailed: fail,
+    onInstallCancelled: fail,
+    onInstallFailed: fail,
+    onInstallEnded: success,
+  };
+
+  let installCallback = install => {
+    install.addListener(listener);
+    install.install();
+  };
+
+  let file = do_get_file(relativePath, false);
+  AddonManager.getInstallForFile(file, installCallback,
+                                 "application/x-xpinstall");
+
+  return deferred.promise;
+}
+
+// Uninstall addon and return a Promise<boolean> that is
+// resolve with true on success, false otherwise.
+function uninstallAddon(id) {
+  let deferred = Promise.defer();
+
+  AddonManager.getAddonByID(id, addon => {
+    if (!addon) {
+      deferred.resolve(false);
+    }
+
+    let listener = {};
+    let handler = addon => {
+      if (addon.id !== id) {
+        return;
+      }
+
+      AddonManager.removeAddonListener(listener);
+      deferred.resolve(true);
+    };
+
+    listener.onUninstalled = handler;
+    listener.onDisabled = handler;
+
+    AddonManager.addAddonListener(listener);
+    addon.uninstall();
+  });
+
+  return deferred.promise;
+}
+
+// Returns a Promise<Addon> that is resolved with
+// the corresponding addon or rejected.
+function getAddonByID(id) {
+  let deferred = Promise.defer();
+  AddonManager.getAddonByID(id, addon => deferred.resolve(addon));
+  return deferred.promise;
+}
new file mode 100644
--- /dev/null
+++ b/dom/plugins/test/unit/test_plugin_default_state_xpi.js
@@ -0,0 +1,108 @@
+/* Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/publicdomain/zero/1.0/
+ */
+
+Cu.import("resource://gre/modules/Services.jsm");
+Cu.import("resource://gre/modules/Promise.jsm");
+
+const ADDON_ID = "test-plugin-from-xpi@tests.mozilla.org";
+const XRE_EXTENSIONS_DIR_LIST = "XREExtDL";
+const NS_APP_PLUGINS_DIR_LIST = "APluginsDL";
+
+const gPluginHost = Cc["@mozilla.org/plugin/host;1"].getService(Ci.nsIPluginHost);
+const gXPCOMABI = Cc["@mozilla.org/xre/app-info;1"].getService(Ci.nsIXULRuntime).XPCOMABI;
+let gProfileDir = null;
+
+function getAddonRoot(profileDir, id) {
+  let dir = profileDir.clone();
+  dir.append("extensions");
+  Assert.ok(dir.exists(), "Extensions dir should exist: " + dir.path);
+  dir.append(id);
+  return dir;
+}
+
+function getTestaddonFilename() {
+  let abiPart = "";
+  if (gIsOSX) {
+    abiPart = "_" + gXPCOMABI;
+  }
+  return "testaddon" + abiPart + ".xpi";
+}
+
+function run_test() {
+  loadAddonManager();
+  gProfileDir = do_get_profile();
+  do_register_cleanup(() => shutdownManager());
+  run_next_test();
+}
+
+add_task(function* test_state() {
+  // Remove test so we will have only one "Test Plug-in" registered.
+  // xpcshell tests have plugins in per-test profiles, so that's fine.
+  let file = get_test_plugin();
+  file.remove(true);
+
+  let success = yield installAddon(getTestaddonFilename());
+  Assert.ok(success, "Should have installed addon.");
+  let addonDir = getAddonRoot(gProfileDir, ADDON_ID);
+
+  let provider = {
+    classID: Components.ID("{0af6b2d7-a06c-49b7-babc-636d292b0dbb}"),
+    QueryInterface: XPCOMUtils.generateQI([Ci.nsIDirectoryServiceProvider,
+                                           Ci.nsIDirectoryServiceProvider2]),
+
+    getFile: function (prop, persistant) {
+      throw Cr.NS_ERROR_FAILURE;
+    },
+
+    getFiles: function (prop) {
+      let result = [];
+
+      switch (prop) {
+      case XRE_EXTENSIONS_DIR_LIST:
+        result.push(addonDir);
+        break;
+      case NS_APP_PLUGINS_DIR_LIST:
+        let pluginDir = addonDir.clone();
+        pluginDir.append("plugins");
+        result.push(pluginDir);
+        break;
+      default:
+        throw Cr.NS_ERROR_FAILURE;
+      }
+
+      return {
+        QueryInterface: XPCOMUtils.generateQI([Ci.nsISimpleEnumerator]),
+        hasMoreElements: () => result.length > 0,
+        getNext: () => result.shift(),
+      };
+    },
+  };
+
+  let dirSvc = Cc["@mozilla.org/file/directory_service;1"].getService(Ci.nsIProperties);
+  dirSvc.QueryInterface(Ci.nsIDirectoryService).registerProvider(provider);
+
+  // We installed a non-restartless addon, need to restart the manager.
+  restartManager();
+  gPluginHost.reloadPlugins();
+
+  Assert.ok(addonDir.exists(), "Addon path should exist: " + addonDir.path);
+  Assert.ok(addonDir.isDirectory(), "Addon path should be a directory: " + addonDir.path);
+  let pluginDir = addonDir.clone();
+  pluginDir.append("plugins");
+  Assert.ok(pluginDir.exists(), "Addon plugins path should exist: " + pluginDir.path);
+  Assert.ok(pluginDir.isDirectory(), "Addon plugins path should be a directory: " + pluginDir.path);
+
+  let addon = yield getAddonByID(ADDON_ID);
+  Assert.ok(!addon.appDisabled, "Addon should not be appDisabled");
+  Assert.ok(addon.isActive, "Addon should be active");
+  Assert.ok(addon.isCompatible, "Addon should be compatible");
+  Assert.ok(!addon.userDisabled, "Addon should not be user disabled");
+
+  let testPlugin = get_test_plugintag();
+  Assert.notEqual(testPlugin, null, "Test plugin should have been found");
+  Assert.equal(testPlugin.enabledState, Ci.nsIPluginTag.STATE_ENABLED, "Test plugin from addon should have state enabled");
+
+  pluginDir.append(testPlugin.filename);
+  Assert.ok(pluginDir.exists(), "Plugin file should exist in addon directory: " + pluginDir.path);
+});
--- a/dom/plugins/test/unit/xpcshell.ini
+++ b/dom/plugins/test/unit/xpcshell.ini
@@ -12,8 +12,9 @@ fail-if = os == "android"
 # Bug 676953: test fails consistently on Android
 fail-if = os == "android"
 [test_nice_plugin_name.js]
 # Bug 676953: test fails consistently on Android
 fail-if = os == "android"
 [test_persist_in_prefs.js]
 [test_bug854467.js]
 [test_plugin_default_state.js]
+[test_plugin_default_state_xpi.js]