Bug 694595: Some settings for add-ons aren't being migrated when we change database schemas. r=Unfocused, a=LegNeato
authorDave Townsend <dtownsend@oxymoronical.com>
Wed, 26 Oct 2011 11:02:23 -0700
changeset 78870 4d7b3566bd134d51475a8288ec85d4c600829690
parent 78869 56032076e440be3c69eda9d259aca49911449e4d
child 78871 3733f8ea953592e8ed2456fa07172020b8d43a61
push id340
push userclegnitto@mozilla.com
push dateTue, 08 Nov 2011 22:56:33 +0000
treeherdermozilla-beta@f745dc151615 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersUnfocused, LegNeato
bugs694595
milestone9.0a2
Bug 694595: Some settings for add-ons aren't being migrated when we change database schemas. r=Unfocused, a=LegNeato
toolkit/mozapps/extensions/XPIProvider.jsm
toolkit/mozapps/extensions/test/addons/test_migrate4_6/install.rdf
toolkit/mozapps/extensions/test/xpcshell/data/test_migrate4.rdf
toolkit/mozapps/extensions/test/xpcshell/test_migrate1.js
toolkit/mozapps/extensions/test/xpcshell/test_migrate2.js
toolkit/mozapps/extensions/test/xpcshell/test_migrate3.js
toolkit/mozapps/extensions/test/xpcshell/test_migrate4.js
toolkit/mozapps/extensions/test/xpcshell/xpcshell.ini
--- a/toolkit/mozapps/extensions/XPIProvider.jsm
+++ b/toolkit/mozapps/extensions/XPIProvider.jsm
@@ -2587,24 +2587,30 @@ var XPIProvider = {
         // A theme's disabled state is determined by the selected theme
         // preference which is read in loadManifestFromRDF
         if (newAddon.type != "theme")
           newAddon.userDisabled = aMigrateData.userDisabled;
         if ("installDate" in aMigrateData)
           newAddon.installDate = aMigrateData.installDate;
         if ("softDisabled" in aMigrateData)
           newAddon.softDisabled = aMigrateData.softDisabled;
+        if ("applyBackgroundUpdates" in aMigrateData)
+          newAddon.applyBackgroundUpdates = aMigrateData.applyBackgroundUpdates;
+        if ("sourceURI" in aMigrateData)
+          newAddon.sourceURI = aMigrateData.sourceURI;
+        if ("releaseNotesURI" in aMigrateData)
+          newAddon.releaseNotesURI = aMigrateData.releaseNotesURI;
 
         // Some properties should only be migrated if the add-on hasn't changed.
         // The version property isn't a perfect check for this but covers the
         // vast majority of cases.
-        if (aMigrateData.version == newAddon.version) {
+        if (aMigrateData.version == newAddon.version &&
+            "targetApplications" in aMigrateData) {
           LOG("Migrating compatibility info");
-          if ("targetApplications" in aMigrateData)
-            newAddon.applyCompatibilityUpdate(aMigrateData, true);
+          newAddon.applyCompatibilityUpdate(aMigrateData, true);
         }
 
         // Since the DB schema has changed make sure softDisabled is correct
         applyBlocklistChanges(newAddon, newAddon, aOldAppVersion,
                               aOldPlatformVersion);
       }
 
       if (aActiveBundles) {
@@ -4334,17 +4340,21 @@ var XPIDatabase = {
 
     // Attempt to migrate data from a different (even future!) version of the
     // database
     try {
       // Build a list of sql statements that might recover useful data from this
       // and future versions of the schema
       var sql = [];
       sql.push("SELECT internal_id, id, location, userDisabled, " +
-               "softDisabled, installDate, version FROM addon");
+               "softDisabled, installDate, version, applyBackgroundUpdates, " +
+               "sourceURI, releaseNotesURI FROM addon");
+      sql.push("SELECT internal_id, id, location, userDisabled, " +
+               "installDate, version, applyBackgroundUpdates, " +
+               "sourceURI, releaseNotesURI FROM addon");
       sql.push("SELECT internal_id, id, location, userDisabled, installDate, " +
                "version FROM addon");
 
       var stmt = null;
       if (!sql.some(function(aSql) {
         try {
           stmt = this.connection.createStatement(aSql);
           return true;
@@ -4365,16 +4375,22 @@ var XPIDatabase = {
           version: row.version,
           installDate: row.installDate,
           userDisabled: row.userDisabled == 1,
           targetApplications: []
         };
 
         if ("softDisabled" in row)
           migrateData[row.location][row.id].softDisabled = row.softDisabled == 1;
+        if ("applyBackgroundUpdates" in row)
+          migrateData[row.location][row.id].applyBackgroundUpdates = row.applyBackgroundUpdates == 1;
+        if ("sourceURI" in row)
+          migrateData[row.location][row.id].sourceURI = row.sourceURI;
+        if ("releaseNotesURI" in row)
+          migrateData[row.location][row.id].releaseNotesURI = row.releaseNotesURI;
       }
 
       var taStmt = this.connection.createStatement("SELECT id, minVersion, " +
                                                    "maxVersion FROM " +
                                                    "targetApplication WHERE " +
                                                    "addon_internal_id=:internal_id");
 
       for (let location in migrateData) {
new file mode 100644
--- /dev/null
+++ b/toolkit/mozapps/extensions/test/addons/test_migrate4_6/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>addon6@tests.mozilla.org</em:id>
+    <em:version>2.0</em:version>
+
+    <!-- Front End MetaData -->
+    <em:name>Test 6</em:name>
+    <em:description>Test Description</em:description>
+
+    <em:targetApplication>
+      <Description>
+        <em:id>xpcshell@tests.mozilla.org</em:id>
+        <em:minVersion>1</em:minVersion>
+        <em:maxVersion>2</em:maxVersion>
+      </Description>
+    </em:targetApplication>
+
+  </Description>
+</RDF>
new file mode 100644
--- /dev/null
+++ b/toolkit/mozapps/extensions/test/xpcshell/data/test_migrate4.rdf
@@ -0,0 +1,46 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<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:extension:addon5@tests.mozilla.org">
+    <em:updates>
+      <Seq>
+        <li>
+          <Description>
+            <em:version>2.0</em:version>
+            <em:targetApplication>
+              <Description>
+                <em:id>xpcshell@tests.mozilla.org</em:id>
+                <em:minVersion>0</em:minVersion>
+                <em:maxVersion>2</em:maxVersion>
+              </Description>
+            </em:targetApplication>
+          </Description>
+        </li>
+      </Seq>
+    </em:updates>
+  </Description>
+
+  <Description about="urn:mozilla:extension:addon6@tests.mozilla.org">
+    <em:updates>
+      <Seq>
+        <li>
+          <Description>
+            <em:version>2.0</em:version>
+            <em:targetApplication>
+              <Description>
+                <em:id>xpcshell@tests.mozilla.org</em:id>
+                <em:minVersion>0</em:minVersion>
+                <em:maxVersion>2</em:maxVersion>
+                <em:updateLink>http://localhost:4444/addons/test_migrate4_6.xpi</em:updateLink>
+                <em:updateInfoURL>http://example.com/updateInfo.xhtml</em:updateInfoURL>
+              </Description>
+            </em:targetApplication>
+          </Description>
+        </li>
+      </Seq>
+    </em:updates>
+  </Description>
+
+</RDF>
--- a/toolkit/mozapps/extensions/test/xpcshell/test_migrate1.js
+++ b/toolkit/mozapps/extensions/test/xpcshell/test_migrate1.js
@@ -1,13 +1,13 @@
 /* Any copyright is dedicated to the Public Domain.
  * http://creativecommons.org/publicdomain/zero/1.0/
  */
 
-// Checks that we migrate data from previous versions of the database
+// Checks that we migrate data from the old rdf style database
 
 var addon1 = {
   id: "addon1@tests.mozilla.org",
   version: "1.0",
   name: "Test 1",
   targetApplications: [{
     id: "xpcshell@tests.mozilla.org",
     minVersion: "1",
--- a/toolkit/mozapps/extensions/test/xpcshell/test_migrate2.js
+++ b/toolkit/mozapps/extensions/test/xpcshell/test_migrate2.js
@@ -172,17 +172,16 @@ function run_test() {
     do_check_false(a4.userDisabled);
     do_check_false(a4.appDisabled);
     do_check_true(a4.isActive);
     // addon5 was enabled in the database but needed a compatibiltiy update
     do_check_neq(a5, null);
     do_check_false(a5.userDisabled);
     do_check_false(a5.appDisabled);
     do_check_true(a5.isActive);
-    do_test_finished();
     // addon6 was disabled and compatible but a new version has been installed
     // since, it should still be disabled but should be incompatible
     do_check_neq(a6, null);
     do_check_true(a6.userDisabled);
     do_check_true(a6.appDisabled);
     do_check_false(a6.isActive);
     do_test_finished();
   });
--- a/toolkit/mozapps/extensions/test/xpcshell/test_migrate3.js
+++ b/toolkit/mozapps/extensions/test/xpcshell/test_migrate3.js
@@ -1,13 +1,13 @@
 /* Any copyright is dedicated to the Public Domain.
  * http://creativecommons.org/publicdomain/zero/1.0/
  */
 
-// Checks that we migrate data from previous versions of the database. This
+// Checks that we migrate data from the old extensions.rdf database. This
 // matches test_migrate1.js however it runs with a lightweight theme selected
 // so the themes should appear disabled.
 
 Components.utils.import("resource://gre/modules/LightweightThemeManager.jsm");
 
 var addon1 = {
   id: "addon1@tests.mozilla.org",
   version: "1.0",
new file mode 100644
--- /dev/null
+++ b/toolkit/mozapps/extensions/test/xpcshell/test_migrate4.js
@@ -0,0 +1,223 @@
+/* Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/publicdomain/zero/1.0/
+ */
+
+// Checks that we migrate data from a previous version of the sqlite database
+
+// The test extension uses an insecure update url.
+Services.prefs.setBoolPref("extensions.checkUpdateSecurity", false);
+
+var addon1 = {
+  id: "addon1@tests.mozilla.org",
+  version: "1.0",
+  name: "Test 1",
+  targetApplications: [{
+    id: "xpcshell@tests.mozilla.org",
+    minVersion: "1",
+    maxVersion: "2"
+  }]
+};
+
+var addon2 = {
+  id: "addon2@tests.mozilla.org",
+  version: "2.0",
+  name: "Test 2",
+  targetApplications: [{
+    id: "xpcshell@tests.mozilla.org",
+    minVersion: "1",
+    maxVersion: "2"
+  }]
+};
+
+var addon3 = {
+  id: "addon3@tests.mozilla.org",
+  version: "2.0",
+  name: "Test 3",
+  targetApplications: [{
+    id: "xpcshell@tests.mozilla.org",
+    minVersion: "1",
+    maxVersion: "2"
+  }]
+};
+
+var addon4 = {
+  id: "addon4@tests.mozilla.org",
+  version: "2.0",
+  name: "Test 4",
+  targetApplications: [{
+    id: "xpcshell@tests.mozilla.org",
+    minVersion: "1",
+    maxVersion: "2"
+  }]
+};
+
+var addon5 = {
+  id: "addon5@tests.mozilla.org",
+  version: "2.0",
+  name: "Test 5",
+  updateURL: "http://localhost:4444/data/test_migrate4.rdf",
+  targetApplications: [{
+    id: "xpcshell@tests.mozilla.org",
+    minVersion: "0",
+    maxVersion: "1"
+  }]
+};
+
+var addon6 = {
+  id: "addon6@tests.mozilla.org",
+  version: "1.0",
+  name: "Test 6",
+  updateURL: "http://localhost:4444/data/test_migrate4.rdf",
+  targetApplications: [{
+    id: "xpcshell@tests.mozilla.org",
+    minVersion: "0",
+    maxVersion: "1"
+  }]
+};
+
+const profileDir = gProfD.clone();
+profileDir.append("extensions");
+
+do_load_httpd_js();
+var testserver;
+
+function prepare_profile() {
+  createAppInfo("xpcshell@tests.mozilla.org", "XPCShell", "1", "1.9.2");
+
+  // Create and configure the HTTP server.
+  testserver = new nsHttpServer();
+  testserver.registerDirectory("/data/", do_get_file("data"));
+  testserver.registerDirectory("/addons/", do_get_file("addons"));
+  testserver.start(4444);
+
+  writeInstallRDFForExtension(addon1, profileDir);
+  writeInstallRDFForExtension(addon2, profileDir);
+  writeInstallRDFForExtension(addon3, profileDir);
+  writeInstallRDFForExtension(addon4, profileDir);
+  writeInstallRDFForExtension(addon5, profileDir);
+  writeInstallRDFForExtension(addon6, profileDir);
+
+  startupManager();
+  AddonManager.getAddonsByIDs(["addon1@tests.mozilla.org",
+                               "addon2@tests.mozilla.org",
+                               "addon3@tests.mozilla.org",
+                               "addon4@tests.mozilla.org",
+                               "addon5@tests.mozilla.org",
+                               "addon6@tests.mozilla.org"],
+                               function([a1, a2, a3, a4, a5, a6]) {
+    a2.userDisabled = true;
+    a2.applyBackgroundUpdates = false;
+    a4.userDisabled = true;
+    a6.userDisabled = true;
+
+    a6.findUpdates({
+      onUpdateAvailable: function(aAddon, aInstall) {
+        completeAllInstalls([aInstall], function() {
+          restartManager();
+
+          AddonManager.getAddonsByIDs(["addon1@tests.mozilla.org",
+                                       "addon2@tests.mozilla.org",
+                                       "addon3@tests.mozilla.org",
+                                       "addon4@tests.mozilla.org",
+                                       "addon5@tests.mozilla.org",
+                                       "addon6@tests.mozilla.org"],
+                                       function([a1, a2, a3, a4, a5, a6]) {
+            a3.userDisabled = true;
+            a4.userDisabled = false;
+
+            a5.findUpdates({
+              onUpdateFinished: function() {
+                shutdownManager();
+
+                perform_migration();
+              }
+            }, AddonManager.UPDATE_WHEN_USER_REQUESTED);
+          });
+        });
+      }
+    }, AddonManager.UPDATE_WHEN_USER_REQUESTED);
+  });
+}
+
+function perform_migration() {
+  let dbfile = gProfD.clone();
+  dbfile.append("extensions.sqlite");
+  let db = AM_Cc["@mozilla.org/storage/service;1"].
+           getService(AM_Ci.mozIStorageService).
+           openDatabase(dbfile);
+  db.schemaVersion = 1;
+  Services.prefs.setIntPref("extensions.databaseSchema", 1);
+  db.close();
+
+  gAppInfo.version = "2"
+  startupManager(true);
+  test_results();
+}
+
+function test_results() {
+  check_startup_changes("installed", []);
+  check_startup_changes("updated", []);
+  check_startup_changes("uninstalled", []);
+  check_startup_changes("disabled", []);
+  check_startup_changes("enabled", []);
+
+  AddonManager.getAddonsByIDs(["addon1@tests.mozilla.org",
+                               "addon2@tests.mozilla.org",
+                               "addon3@tests.mozilla.org",
+                               "addon4@tests.mozilla.org",
+                               "addon5@tests.mozilla.org",
+                               "addon6@tests.mozilla.org"],
+                               function([a1, a2, a3, a4, a5, a6]) {
+    // addon1 was enabled
+    do_check_neq(a1, null);
+    do_check_false(a1.userDisabled);
+    do_check_false(a1.appDisabled);
+    do_check_true(a1.isActive);
+    do_check_true(a1.applyBackgroundUpdates);
+
+    // addon2 was disabled
+    do_check_neq(a2, null);
+    do_check_true(a2.userDisabled);
+    do_check_false(a2.appDisabled);
+    do_check_false(a2.isActive);
+    do_check_false(a2.applyBackgroundUpdates);
+
+    // addon3 was pending-disable in the database
+    do_check_neq(a3, null);
+    do_check_true(a3.userDisabled);
+    do_check_false(a3.appDisabled);
+    do_check_false(a3.isActive);
+    do_check_true(a3.applyBackgroundUpdates);
+
+    // addon4 was pending-enable in the database
+    do_check_neq(a4, null);
+    do_check_false(a4.userDisabled);
+    do_check_false(a4.appDisabled);
+    do_check_true(a4.isActive);
+    do_check_true(a4.applyBackgroundUpdates);
+
+    // addon5 was enabled in the database but needed a compatibiltiy update
+    do_check_neq(a5, null);
+    do_check_false(a5.userDisabled);
+    do_check_false(a5.appDisabled);
+    do_check_true(a5.isActive);
+    do_check_true(a5.applyBackgroundUpdates);
+
+    // addon6 was disabled and compatible but a new version has been installed
+    do_check_neq(a6, null);
+    do_check_eq(a6.version, "2.0");
+    do_check_true(a6.userDisabled);
+    do_check_false(a6.appDisabled);
+    do_check_false(a6.isActive);
+    do_check_true(a6.applyBackgroundUpdates);
+    do_check_eq(a6.sourceURI.spec, "http://localhost:4444/addons/test_migrate4_6.xpi");
+    do_check_eq(a6.releaseNotesURI.spec, "http://example.com/updateInfo.xhtml");
+    testserver.stop(do_test_finished);
+  });
+}
+
+function run_test() {
+  do_test_pending();
+
+  prepare_profile();
+}
--- a/toolkit/mozapps/extensions/test/xpcshell/xpcshell.ini
+++ b/toolkit/mozapps/extensions/test/xpcshell/xpcshell.ini
@@ -152,16 +152,17 @@ skip-if = os == "android"
 # Bug 676992: test consistently hangs on Android
 skip-if = os == "android"
 [test_locale.js]
 [test_locked.js]
 [test_manifest.js]
 [test_migrate1.js]
 [test_migrate2.js]
 [test_migrate3.js]
+[test_migrate4.js]
 [test_migrateAddonRepository.js]
 [test_permissions.js]
 [test_plugins.js]
 # Bug 676992: test consistently fails on Android
 fail-if = os == "android"
 [test_registry.js]
 [test_safemode.js]
 [test_startup.js]