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
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 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;
-
-/**
- * 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");
-  },
+var chrome = Components.classes["@mozilla.org/chrome/chrome-registry;1"]
+  .getService(Components.interfaces.nsIXULChromeRegistry);
 
-  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();
-    });
-  });
-}
-
-// 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();
-        });
-      });
+      do_test_finished();
     });
   });
 }
-
-// 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"