bug 677092, make language packs restartless, r=Unfocused
authorAxel Hecht <axel@pike.org>
Thu, 20 Sep 2012 10:01:39 +0200
changeset 108130 812d0ba83175
parent 108129 97e49e7a3326
child 108131 3688310dce70
push id23539
push userryanvm@gmail.com
push date2012-09-26 22:55 +0000
treeherdermozilla-central@ec079fd92224 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersUnfocused
bugs677092
milestone18.0a1
bug 677092, make language packs restartless, r=Unfocused
Make language packs just trigger the chrome registration hooks, and
disable picking up bootstrap.js, and declare them restartless.
build/valgrind/x86_64-redhat-linux-gnu.sup
toolkit/mozapps/extensions/XPIProvider.jsm
toolkit/mozapps/extensions/test/addons/test_langpack/chrome.manifest
toolkit/mozapps/extensions/test/addons/test_langpack/install.rdf
toolkit/mozapps/extensions/test/xpcshell/test_langpack.js
toolkit/mozapps/extensions/test/xpcshell/xpcshell.ini
--- a/toolkit/mozapps/extensions/XPIProvider.jsm
+++ b/toolkit/mozapps/extensions/XPIProvider.jsm
@@ -735,18 +735,18 @@ function loadManifestFromRDF(aUri, aStre
     if (addon.optionsType &&
         addon.optionsType != AddonManager.OPTIONS_TYPE_DIALOG &&
         addon.optionsType != AddonManager.OPTIONS_TYPE_INLINE &&
         addon.optionsType != AddonManager.OPTIONS_TYPE_TAB) {
       throw new Error("Install manifest specifies unknown type: " + addon.optionsType);
     }
   }
   else {
-    // spell check dictionaries never require a restart
-    if (addon.type == "dictionary")
+    // spell check dictionaries and language packs never require a restart
+    if (addon.type == "dictionary" || addon.type == "locale")
       addon.bootstrap = true;
 
     // Only extensions are allowed to provide an optionsURL, optionsType or aboutURL. For
     // all other types they are silently ignored
     addon.optionsURL = null;
     addon.optionsType = null;
     addon.aboutURL = null;
 
@@ -3690,16 +3690,21 @@ var XPIProvider = {
     // Never call any bootstrap methods in safe mode
     if (Services.appinfo.inSafeMode)
       return;
 
     if (aMethod == "startup")
       Components.manager.addBootstrappedManifestLocation(aFile);
 
     try {
+      // Don't call bootstrap.js methods for language packs,
+      // they only contain chrome.
+      if (aType == "locale")
+         return;
+
       // Load the scope if it hasn't already been loaded
       if (!(aId in this.bootstrapScopes))
         this.loadBootstrapScope(aId, aFile, aVersion, aType);
 
       if (!(aMethod in this.bootstrapScopes[aId])) {
         WARN("Add-on " + aId + " is missing bootstrap method " + aMethod);
         return;
       }
copy from toolkit/mozapps/extensions/test/addons/test_chromemanifest_1/chrome.manifest
copy to toolkit/mozapps/extensions/test/addons/test_langpack/chrome.manifest
--- a/toolkit/mozapps/extensions/test/addons/test_chromemanifest_1/chrome.manifest
+++ b/toolkit/mozapps/extensions/test/addons/test_langpack/chrome.manifest
@@ -1,6 +1,1 @@
-content test-addon-1 chrome/content
-# comment!  
-  locale test-addon-1 en-US locale/en-US
-      # commentaire!  
-  locale test-addon-1    fr-FR locale/fr-FR  
-overlay	chrome://browser/content/browser.xul    chrome://test-addon-1/content/overlay.xul
+locale test-langpack    x-testing locale/x-testing
copy from toolkit/mozapps/extensions/test/addons/test_chromemanifest_1/install.rdf
copy to toolkit/mozapps/extensions/test/addons/test_langpack/install.rdf
--- a/toolkit/mozapps/extensions/test/addons/test_chromemanifest_1/install.rdf
+++ b/toolkit/mozapps/extensions/test/addons/test_langpack/install.rdf
@@ -1,20 +1,20 @@
 <?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>addon1@tests.mozilla.org</em:id>
+    <em:id>langpack-x-testing@tests.mozilla.org</em:id>
+    <em:type>8</em:type>
     <em:version>1.0</em:version>
 
     <!-- Front End MetaData -->
-    <em:name>Test 1</em:name>
-    <em:description>Test Description</em:description>
+    <em:name>Language Pack x-testing</em:name>
 
     <em:targetApplication>
       <Description>
         <em:id>xpcshell@tests.mozilla.org</em:id>
         <em:minVersion>1</em:minVersion>
         <em:maxVersion>2</em:maxVersion>
       </Description>
     </em:targetApplication>
copy from toolkit/mozapps/extensions/test/xpcshell/test_dictionary.js
copy to toolkit/mozapps/extensions/test/xpcshell/test_langpack.js
--- a/toolkit/mozapps/extensions/test/xpcshell/test_dictionary.js
+++ b/toolkit/mozapps/extensions/test/xpcshell/test_langpack.js
@@ -1,641 +1,247 @@
 /* Any copyright is dedicated to the Public Domain.
  * http://creativecommons.org/publicdomain/zero/1.0/
  */
 
-// This verifies that bootstrappable add-ons can be used without restarts.
+// This verifies that language packs can be used without restarts.
 Components.utils.import("resource://gre/modules/Services.jsm");
 
 // Enable loading extensions from the user scopes
 Services.prefs.setIntPref("extensions.enabledScopes",
                           AddonManager.SCOPE_PROFILE + AddonManager.SCOPE_USER);
 
 createAppInfo("xpcshell@tests.mozilla.org", "XPCShell", "1", "1.9.2");
 
 const profileDir = gProfD.clone();
 profileDir.append("extensions");
 const userExtDir = gProfD.clone();
 userExtDir.append("extensions2");
 userExtDir.append(gAppInfo.ID);
 registerDirectory("XREUSysExt", userExtDir.parent);
 
-Components.utils.import("resource://testing-common/httpd.js");
-var testserver;
+var chrome = Components.classes["@mozilla.org/chrome/chrome-registry;1"]
+  .getService(Components.interfaces.nsIXULChromeRegistry);
 
-/**
- * This object is both a factory and an mozISpellCheckingEngine implementation (so, it
- * is de-facto a service). It's also an interface requestor that gives out
- * itself when asked for mozISpellCheckingEngine.
- */
-var HunspellEngine = {
-  dictionaryDirs: [],
-  listener: null,
-  
-  QueryInterface: function hunspell_qi(iid) {
-    if (iid.equals(Components.interfaces.nsISupports) ||
-        iid.equals(Components.interfaces.nsIFactory) ||
-        iid.equals(Components.interfaces.mozISpellCheckingEngine))
-      return this;
-    throw Components.results.NS_ERROR_NO_INTERFACE;
-  },
-  createInstance: function hunspell_ci(outer, iid) {
-    if (outer)
-      throw Components.results.NS_ERROR_NO_AGGREGATION;
-    return this.QueryInterface(iid);
-  },
-  lockFactory: function hunspell_lockf(lock) {
-    throw Components.results.NS_ERROR_NOT_IMPLEMENTED;
-  },
-
-  addDirectory: function hunspell_addDirectory(dir) {
-    this.dictionaryDirs.push(dir);
-    if (this.listener)
-      this.listener("addDirectory");
-  },
-
-  removeDirectory: function hunspell_addDirectory(dir) {
-    this.dictionaryDirs.splice(this.dictionaryDirs.indexOf(dir), 1);
-    if (this.listener)
-      this.listener("removeDirectory");
-  },
-
-  getInterface: function hunspell_gi(iid) {
-    if (iid.equals(Components.interfaces.mozISpellCheckingEngine))
-      return this;
-    throw Components.results.NS_ERROR_NO_INTERFACE;
-  },
-
-  contractID: "@mozilla.org/spellchecker/engine;1",
-  classID: Components.ID("{6f3c63bc-a4fd-449b-9a58-a2d9bd972cce}"),
-
-  activate: function hunspell_activate() {
-    this.origClassID = Components.manager.nsIComponentRegistrar
-      .contractIDToCID(this.contractID);
-    this.origFactory = Components.manager
-      .getClassObject(Components.classes[this.contractID],
-                      Components.interfaces.nsIFactory);
-
-    Components.manager.nsIComponentRegistrar
-      .unregisterFactory(this.origClassID, this.origFactory);
-    Components.manager.nsIComponentRegistrar.registerFactory(this.classID,
-      "Test hunspell", this.contractID, this);
-  },
-  
-  deactivate: function hunspell_deactivate() {
-    Components.manager.nsIComponentRegistrar.unregisterFactory(this.classID, this);
-    Components.manager.nsIComponentRegistrar.registerFactory(this.origClassID,
-      "Hunspell", this.contractID, this.origFactory);
-  },
-
-  isDictionaryEnabled: function hunspell_isDictionaryEnabled(name) {
-    return this.dictionaryDirs.some(function(dir) {
-      var dic = dir.clone();
-      dic.append(name);
-      return dic.exists();
-    });
+function do_check_locale_not_registered(provider) {
+  let didThrow = false;
+  try {
+    chrome.getSelectedLocale(provider);
+  } catch (e) {
+    didThrow = true;
   }
-};
+  do_check_true(didThrow);
+}
 
 function run_test() {
   do_test_pending();
 
-  // Create and configure the HTTP server.
-  testserver = new HttpServer();
-  testserver.registerDirectory("/addons/", do_get_file("addons"));
-  testserver.start(4444);
-
   startupManager();
 
   run_test_1();
 }
 
 // Tests that installing doesn't require a restart
 function run_test_1() {
   prepare_test({ }, [
     "onNewInstall"
   ]);
 
-  HunspellEngine.activate();
-
-  AddonManager.getInstallForFile(do_get_addon("test_dictionary"), function(install) {
+  AddonManager.getInstallForFile(do_get_addon("test_langpack"), function(install) {
     ensure_test_completed();
 
     do_check_neq(install, null);
-    do_check_eq(install.type, "dictionary");
+    do_check_eq(install.type, "locale");
     do_check_eq(install.version, "1.0");
-    do_check_eq(install.name, "Test Dictionary");
+    do_check_eq(install.name, "Language Pack x-testing");
     do_check_eq(install.state, AddonManager.STATE_DOWNLOADED);
     do_check_true(install.addon.hasResource("install.rdf"));
     do_check_false(install.addon.hasResource("bootstrap.js"));
     do_check_eq(install.addon.operationsRequiringRestart &
                 AddonManager.OP_NEEDS_RESTART_INSTALL, 0);
-    do_check_not_in_crash_annotation("ab-CD@dictionaries.addons.mozilla.org", "1.0");
 
     let addon = install.addon;
     prepare_test({
-      "ab-CD@dictionaries.addons.mozilla.org": [
+      "langpack-x-testing@tests.mozilla.org": [
         ["onInstalling", false],
         "onInstalled"
       ]
     }, [
       "onInstallStarted",
       "onInstallEnded",
     ], function() {
       do_check_true(addon.hasResource("install.rdf"));
-      HunspellEngine.listener = function(aEvent) {
-        HunspellEngine.listener = null;
-        do_check_eq(aEvent, "addDirectory");
-        check_test_1();
-      };
+      check_test_1();
     });
     install.install();
   });
 }
 
 function check_test_1() {
   AddonManager.getAllInstalls(function(installs) {
     // There should be no active installs now since the install completed and
     // doesn't require a restart.
     do_check_eq(installs.length, 0);
 
-    AddonManager.getAddonByID("ab-CD@dictionaries.addons.mozilla.org", function(b1) {
+    AddonManager.getAddonByID("langpack-x-testing@tests.mozilla.org", function(b1) {
       do_check_neq(b1, null);
       do_check_eq(b1.version, "1.0");
       do_check_false(b1.appDisabled);
       do_check_false(b1.userDisabled);
       do_check_true(b1.isActive);
-      do_check_true(HunspellEngine.isDictionaryEnabled("ab-CD.dic"));
+      // check chrome reg that language pack is registered
+      do_check_eq(chrome.getSelectedLocale("test-langpack"), "x-testing");
       do_check_true(b1.hasResource("install.rdf"));
       do_check_false(b1.hasResource("bootstrap.js"));
-      do_check_in_crash_annotation("ab-CD@dictionaries.addons.mozilla.org", "1.0");
 
-      let dir = do_get_addon_root_uri(profileDir, "ab-CD@dictionaries.addons.mozilla.org");
+      let dir = do_get_addon_root_uri(profileDir, "langpack-x-testing@tests.mozilla.org");
 
       AddonManager.getAddonsWithOperationsByTypes(null, function(list) {
         do_check_eq(list.length, 0);
 
         run_test_2();
       });
     });
   });
 }
 
 // Tests that disabling doesn't require a restart
 function run_test_2() {
-  AddonManager.getAddonByID("ab-CD@dictionaries.addons.mozilla.org", function(b1) {
+  AddonManager.getAddonByID("langpack-x-testing@tests.mozilla.org", function(b1) {
     prepare_test({
-      "ab-CD@dictionaries.addons.mozilla.org": [
+      "langpack-x-testing@tests.mozilla.org": [
         ["onDisabling", false],
         "onDisabled"
       ]
     });
 
     do_check_eq(b1.operationsRequiringRestart &
                 AddonManager.OP_NEEDS_RESTART_DISABLE, 0);
     b1.userDisabled = true;
     ensure_test_completed();
 
     do_check_neq(b1, null);
     do_check_eq(b1.version, "1.0");
     do_check_false(b1.appDisabled);
     do_check_true(b1.userDisabled);
     do_check_false(b1.isActive);
-    do_check_false(HunspellEngine.isDictionaryEnabled("ab-CD.dic"));
-    do_check_not_in_crash_annotation("ab-CD@dictionaries.addons.mozilla.org", "1.0");
+    // check chrome reg that language pack is not registered
+    do_check_locale_not_registered("test-langpack");
 
-    AddonManager.getAddonByID("ab-CD@dictionaries.addons.mozilla.org", function(newb1) {
+    AddonManager.getAddonByID("langpack-x-testing@tests.mozilla.org", function(newb1) {
       do_check_neq(newb1, null);
       do_check_eq(newb1.version, "1.0");
       do_check_false(newb1.appDisabled);
       do_check_true(newb1.userDisabled);
       do_check_false(newb1.isActive);
 
       run_test_3();
     });
   });
 }
 
 // Test that restarting doesn't accidentally re-enable
 function run_test_3() {
   shutdownManager();
-  do_check_false(HunspellEngine.isDictionaryEnabled("ab-CD.dic"));
   startupManager(false);
-  do_check_false(HunspellEngine.isDictionaryEnabled("ab-CD.dic"));
-  do_check_not_in_crash_annotation("ab-CD@dictionaries.addons.mozilla.org", "1.0");
+  // check chrome reg that language pack is not registered
+  do_check_locale_not_registered("test-langpack");
 
-  AddonManager.getAddonByID("ab-CD@dictionaries.addons.mozilla.org", function(b1) {
+  AddonManager.getAddonByID("langpack-x-testing@tests.mozilla.org", function(b1) {
     do_check_neq(b1, null);
     do_check_eq(b1.version, "1.0");
     do_check_false(b1.appDisabled);
     do_check_true(b1.userDisabled);
     do_check_false(b1.isActive);
 
     run_test_4();
   });
 }
 
 // Tests that enabling doesn't require a restart
 function run_test_4() {
-  AddonManager.getAddonByID("ab-CD@dictionaries.addons.mozilla.org", function(b1) {
+  AddonManager.getAddonByID("langpack-x-testing@tests.mozilla.org", function(b1) {
     prepare_test({
-      "ab-CD@dictionaries.addons.mozilla.org": [
+      "langpack-x-testing@tests.mozilla.org": [
         ["onEnabling", false],
         "onEnabled"
       ]
     });
 
     do_check_eq(b1.operationsRequiringRestart &
                 AddonManager.OP_NEEDS_RESTART_ENABLE, 0);
     b1.userDisabled = false;
     ensure_test_completed();
 
     do_check_neq(b1, null);
     do_check_eq(b1.version, "1.0");
     do_check_false(b1.appDisabled);
     do_check_false(b1.userDisabled);
     do_check_true(b1.isActive);
-    do_check_true(HunspellEngine.isDictionaryEnabled("ab-CD.dic"));
-    do_check_in_crash_annotation("ab-CD@dictionaries.addons.mozilla.org", "1.0");
+    // check chrome reg that language pack is registered
+    do_check_eq(chrome.getSelectedLocale("test-langpack"), "x-testing");
 
-    AddonManager.getAddonByID("ab-CD@dictionaries.addons.mozilla.org", function(newb1) {
+    AddonManager.getAddonByID("langpack-x-testing@tests.mozilla.org", function(newb1) {
       do_check_neq(newb1, null);
       do_check_eq(newb1.version, "1.0");
       do_check_false(newb1.appDisabled);
       do_check_false(newb1.userDisabled);
       do_check_true(newb1.isActive);
 
       run_test_5();
     });
   });
 }
 
 // Tests that a restart shuts down and restarts the add-on
 function run_test_5() {
   shutdownManager();
-  do_check_false(HunspellEngine.isDictionaryEnabled("ab-CD.dic"));
-  do_check_not_in_crash_annotation("ab-CD@dictionaries.addons.mozilla.org", "1.0");
   startupManager(false);
-  do_check_true(HunspellEngine.isDictionaryEnabled("ab-CD.dic"));
-  do_check_in_crash_annotation("ab-CD@dictionaries.addons.mozilla.org", "1.0");
+  // check chrome reg that language pack is registered
+  do_check_eq(chrome.getSelectedLocale("test-langpack"), "x-testing");
 
-  AddonManager.getAddonByID("ab-CD@dictionaries.addons.mozilla.org", function(b1) {
+  AddonManager.getAddonByID("langpack-x-testing@tests.mozilla.org", function(b1) {
     do_check_neq(b1, null);
     do_check_eq(b1.version, "1.0");
     do_check_false(b1.appDisabled);
     do_check_false(b1.userDisabled);
     do_check_true(b1.isActive);
     do_check_false(isExtensionInAddonsList(profileDir, b1.id));
 
     run_test_7();
   });
 }
 
 // Tests that uninstalling doesn't require a restart
 function run_test_7() {
-  AddonManager.getAddonByID("ab-CD@dictionaries.addons.mozilla.org", function(b1) {
+  AddonManager.getAddonByID("langpack-x-testing@tests.mozilla.org", function(b1) {
     prepare_test({
-      "ab-CD@dictionaries.addons.mozilla.org": [
+      "langpack-x-testing@tests.mozilla.org": [
         ["onUninstalling", false],
         "onUninstalled"
       ]
     });
 
     do_check_eq(b1.operationsRequiringRestart &
                 AddonManager.OP_NEEDS_RESTART_UNINSTALL, 0);
     b1.uninstall();
 
     check_test_7();
   });
 }
 
 function check_test_7() {
   ensure_test_completed();
-  do_check_false(HunspellEngine.isDictionaryEnabled("ab-CD.dic"));
-  do_check_not_in_crash_annotation("ab-CD@dictionaries.addons.mozilla.org", "1.0");
+  // check chrome reg that language pack is not registered
+  do_check_locale_not_registered("test-langpack");
 
-  AddonManager.getAddonByID("ab-CD@dictionaries.addons.mozilla.org", function(b1) {
+  AddonManager.getAddonByID("langpack-x-testing@tests.mozilla.org", function(b1) {
     do_check_eq(b1, null);
 
     restartManager();
 
-    AddonManager.getAddonByID("ab-CD@dictionaries.addons.mozilla.org", function(newb1) {
+    AddonManager.getAddonByID("langpack-x-testing@tests.mozilla.org", function(newb1) {
       do_check_eq(newb1, null);
 
-      run_test_8();
+      do_test_finished();
     });
   });
 }
-
-// Test that a bootstrapped extension dropped into the profile loads properly
-// on startup and doesn't cause an EM restart
-function run_test_8() {
-  shutdownManager();
-
-  let dir = profileDir.clone();
-  dir.append("ab-CD@dictionaries.addons.mozilla.org");
-  dir.create(AM_Ci.nsIFile.DIRECTORY_TYPE, 0755);
-  let zip = AM_Cc["@mozilla.org/libjar/zip-reader;1"].
-            createInstance(AM_Ci.nsIZipReader);
-  zip.open(do_get_addon("test_dictionary"));
-  dir.append("install.rdf");
-  zip.extract("install.rdf", dir);
-  dir = dir.parent;
-  dir.append("dictionaries");
-  dir.create(AM_Ci.nsIFile.DIRECTORY_TYPE, 0755);
-  dir.append("ab-CD.dic");
-  zip.extract("dictionaries/ab-CD.dic", dir);
-  zip.close();
-
-  startupManager(false);
-
-  AddonManager.getAddonByID("ab-CD@dictionaries.addons.mozilla.org", function(b1) {
-    do_check_neq(b1, null);
-    do_check_eq(b1.version, "1.0");
-    do_check_false(b1.appDisabled);
-    do_check_false(b1.userDisabled);
-    do_check_true(b1.isActive);
-    do_check_true(HunspellEngine.isDictionaryEnabled("ab-CD.dic"));
-    do_check_in_crash_annotation("ab-CD@dictionaries.addons.mozilla.org", "1.0");
-
-    run_test_9();
-  });
-}
-
-// Test that items detected as removed during startup get removed properly
-function run_test_9() {
-  shutdownManager();
-
-  let dir = profileDir.clone();
-  dir.append("ab-CD@dictionaries.addons.mozilla.org");
-  dir.remove(true);
-  startupManager(false);
-
-  AddonManager.getAddonByID("ab-CD@dictionaries.addons.mozilla.org", function(b1) {
-    do_check_eq(b1, null);
-    do_check_not_in_crash_annotation("ab-CD@dictionaries.addons.mozilla.org", "1.0");
-
-    run_test_12();
-  });
-}
-
-
-// Tests that bootstrapped extensions are correctly loaded even if the app is
-// upgraded at the same time
-function run_test_12() {
-  shutdownManager();
-
-  let dir = profileDir.clone();
-  dir.append("ab-CD@dictionaries.addons.mozilla.org");
-  dir.create(AM_Ci.nsIFile.DIRECTORY_TYPE, 0755);
-  let zip = AM_Cc["@mozilla.org/libjar/zip-reader;1"].
-            createInstance(AM_Ci.nsIZipReader);
-  zip.open(do_get_addon("test_dictionary"));
-  dir.append("install.rdf");
-  zip.extract("install.rdf", dir);
-  dir = dir.parent;
-  dir.append("dictionaries");
-  dir.create(AM_Ci.nsIFile.DIRECTORY_TYPE, 0755);
-  dir.append("ab-CD.dic");
-  zip.extract("dictionaries/ab-CD.dic", dir);
-  zip.close();
-
-  startupManager(true);
-
-  AddonManager.getAddonByID("ab-CD@dictionaries.addons.mozilla.org", function(b1) {
-    do_check_neq(b1, null);
-    do_check_eq(b1.version, "1.0");
-    do_check_false(b1.appDisabled);
-    do_check_false(b1.userDisabled);
-    do_check_true(b1.isActive);
-    do_check_true(HunspellEngine.isDictionaryEnabled("ab-CD.dic"));
-    do_check_in_crash_annotation("ab-CD@dictionaries.addons.mozilla.org", "1.0");
-
-    b1.uninstall();
-    restartManager();
-
-    run_test_16();
-  });
-}
-
-
-// Tests that bootstrapped extensions don't get loaded when in safe mode
-function run_test_16() {
-  installAllFiles([do_get_addon("test_dictionary")], function() {
-    AddonManager.getAddonByID("ab-CD@dictionaries.addons.mozilla.org", function(b1) {
-      // Should have installed and started
-      do_check_true(HunspellEngine.isDictionaryEnabled("ab-CD.dic"));
-
-      shutdownManager();
-
-      // Should have stopped
-      do_check_false(HunspellEngine.isDictionaryEnabled("ab-CD.dic"));
-
-      gAppInfo.inSafeMode = true;
-      startupManager(false);
-
-      AddonManager.getAddonByID("ab-CD@dictionaries.addons.mozilla.org", function(b1) {
-        // Should still be stopped
-        do_check_false(HunspellEngine.isDictionaryEnabled("ab-CD.dic"));
-        do_check_false(b1.isActive);
-
-        shutdownManager();
-        gAppInfo.inSafeMode = false;
-        startupManager(false);
-
-        // Should have started
-        do_check_true(HunspellEngine.isDictionaryEnabled("ab-CD.dic"));
-
-        AddonManager.getAddonByID("ab-CD@dictionaries.addons.mozilla.org", function(b1) {
-          b1.uninstall();
-
-          run_test_17();
-        });
-      });
-    });
-  });
-}
-
-// Check that a bootstrapped extension in a non-profile location is loaded
-function run_test_17() {
-  shutdownManager();
-
-  let dir = userExtDir.clone();
-  dir.append("ab-CD@dictionaries.addons.mozilla.org");
-  dir.create(AM_Ci.nsIFile.DIRECTORY_TYPE, 0755);
-  let zip = AM_Cc["@mozilla.org/libjar/zip-reader;1"].
-            createInstance(AM_Ci.nsIZipReader);
-  zip.open(do_get_addon("test_dictionary"));
-  dir.append("install.rdf");
-  zip.extract("install.rdf", dir);
-  dir = dir.parent;
-  dir.append("dictionaries");
-  dir.create(AM_Ci.nsIFile.DIRECTORY_TYPE, 0755);
-  dir.append("ab-CD.dic");
-  zip.extract("dictionaries/ab-CD.dic", dir);
-  zip.close();
-
-  startupManager();
-
-  AddonManager.getAddonByID("ab-CD@dictionaries.addons.mozilla.org", function(b1) {
-    // Should have installed and started
-    do_check_true(HunspellEngine.isDictionaryEnabled("ab-CD.dic"));
-    do_check_neq(b1, null);
-    do_check_eq(b1.version, "1.0");
-    do_check_true(b1.isActive);
-
-    // From run_test_21
-    dir = userExtDir.clone();
-    dir.append("ab-CD@dictionaries.addons.mozilla.org");
-    dir.remove(true);
-
-    restartManager();
-
-    run_test_23();
-  });
-}
-
-// Tests that installing from a URL doesn't require a restart
-function run_test_23() {
-  prepare_test({ }, [
-    "onNewInstall"
-  ]);
-
-  let url = "http://localhost:4444/addons/test_dictionary.xpi";
-  AddonManager.getInstallForURL(url, function(install) {
-    ensure_test_completed();
-
-    do_check_neq(install, null);
-
-    prepare_test({ }, [
-      "onDownloadStarted",
-      "onDownloadEnded"
-    ], function() {
-      do_check_eq(install.type, "dictionary");
-      do_check_eq(install.version, "1.0");
-      do_check_eq(install.name, "Test Dictionary");
-      do_check_eq(install.state, AddonManager.STATE_DOWNLOADED);
-      do_check_true(install.addon.hasResource("install.rdf"));
-      do_check_false(install.addon.hasResource("bootstrap.js"));
-      do_check_eq(install.addon.operationsRequiringRestart &
-                  AddonManager.OP_NEEDS_RESTART_INSTALL, 0);
-      do_check_not_in_crash_annotation("ab-CD@dictionaries.addons.mozilla.org", "1.0");
-
-      let addon = install.addon;
-      prepare_test({
-        "ab-CD@dictionaries.addons.mozilla.org": [
-          ["onInstalling", false],
-          "onInstalled"
-        ]
-      }, [
-        "onInstallStarted",
-        "onInstallEnded",
-      ], function() {
-        do_check_true(addon.hasResource("install.rdf"));
-        check_test_23();
-      });
-    });
-    install.install();
-  }, "application/x-xpinstall");
-}
-
-function check_test_23() {
-  AddonManager.getAllInstalls(function(installs) {
-    // There should be no active installs now since the install completed and
-    // doesn't require a restart.
-    do_check_eq(installs.length, 0);
-
-    AddonManager.getAddonByID("ab-CD@dictionaries.addons.mozilla.org", function(b1) {
-      do_check_neq(b1, null);
-      do_check_eq(b1.version, "1.0");
-      do_check_false(b1.appDisabled);
-      do_check_false(b1.userDisabled);
-      do_check_true(b1.isActive);
-      do_check_true(HunspellEngine.isDictionaryEnabled("ab-CD.dic"));
-      do_check_true(b1.hasResource("install.rdf"));
-      do_check_false(b1.hasResource("bootstrap.js"));
-      do_check_in_crash_annotation("ab-CD@dictionaries.addons.mozilla.org", "1.0");
-
-      let dir = do_get_addon_root_uri(profileDir, "ab-CD@dictionaries.addons.mozilla.org");
-
-      AddonManager.getAddonsWithOperationsByTypes(null, function(list) {
-        do_check_eq(list.length, 0);
-
-        restartManager();
-        AddonManager.getAddonByID("ab-CD@dictionaries.addons.mozilla.org", function(b1) {
-          b1.uninstall();
-          restartManager();
-
-          testserver.stop(run_test_25);
-        });
-      });
-    });
-  });
-}
-
-// Tests that updating from a bootstrappable add-on to a normal add-on calls
-// the uninstall method
-function run_test_25() {
-  installAllFiles([do_get_addon("test_dictionary")], function() {
-    HunspellEngine.listener = function(aEvent) {
-      HunspellEngine.listener = null;
-      do_check_eq(aEvent, "addDirectory");
-      do_check_true(HunspellEngine.isDictionaryEnabled("ab-CD.dic"));
-  
-      installAllFiles([do_get_addon("test_dictionary_2")], function() {
-        // Needs a restart to complete this so the old version stays running
-        do_check_true(HunspellEngine.isDictionaryEnabled("ab-CD.dic"));
-  
-        AddonManager.getAddonByID("ab-CD@dictionaries.addons.mozilla.org", function(b1) {
-          do_check_neq(b1, null);
-          do_check_eq(b1.version, "1.0");
-          do_check_true(b1.isActive);
-          do_check_true(hasFlag(b1.pendingOperations, AddonManager.PENDING_UPGRADE));
-  
-          restartManager();
-  
-          do_check_false(HunspellEngine.isDictionaryEnabled("ab-CD.dic"));
-  
-          AddonManager.getAddonByID("ab-CD@dictionaries.addons.mozilla.org", function(b1) {
-            do_check_neq(b1, null);
-            do_check_eq(b1.version, "2.0");
-            do_check_true(b1.isActive);
-            do_check_eq(b1.pendingOperations, AddonManager.PENDING_NONE);
-  
-            run_test_26();
-          });
-        });
-      });
-    };
-  });
-}
-
-// Tests that updating from a normal add-on to a bootstrappable add-on calls
-// the install method
-function run_test_26() {
-  installAllFiles([do_get_addon("test_dictionary")], function() {
-    // Needs a restart to complete this
-    do_check_false(HunspellEngine.isDictionaryEnabled("ab-CD.dic"));
-
-    AddonManager.getAddonByID("ab-CD@dictionaries.addons.mozilla.org", function(b1) {
-      do_check_neq(b1, null);
-      do_check_eq(b1.version, "2.0");
-      do_check_true(b1.isActive);
-      do_check_true(hasFlag(b1.pendingOperations, AddonManager.PENDING_UPGRADE));
-
-      restartManager();
-
-      do_check_true(HunspellEngine.isDictionaryEnabled("ab-CD.dic"));
-
-      AddonManager.getAddonByID("ab-CD@dictionaries.addons.mozilla.org", function(b1) {
-        do_check_neq(b1, null);
-        do_check_eq(b1.version, "1.0");
-        do_check_true(b1.isActive);
-        do_check_eq(b1.pendingOperations, AddonManager.PENDING_NONE);
-
-        HunspellEngine.deactivate();
-
-        do_test_finished();
-      });
-    });
-  });
-}
-
--- a/toolkit/mozapps/extensions/test/xpcshell/xpcshell.ini
+++ b/toolkit/mozapps/extensions/test/xpcshell/xpcshell.ini
@@ -134,16 +134,17 @@ fail-if = os == "android"
 [test_cacheflush.js]
 [test_checkcompatibility.js]
 [test_ChromeManifestParser.js]
 [test_compatoverrides.js]
 [test_corrupt.js]
 [test_corrupt_strictcompat.js]
 [test_db_sanity.js]
 [test_dictionary.js]
+[test_langpack.js]
 [test_disable.js]
 [test_distribution.js]
 [test_dss.js]
 # Bug 676992: test consistently fails on Android
 fail-if = os == "android"
 [test_duplicateplugins.js]
 # Bug 676992: test consistently hangs on Android
 skip-if = os == "android"