Bug 694595: Some settings for add-ons aren't being migrated when we change database schemas. r=Unfocused
authorDave Townsend <dtownsend@oxymoronical.com>
Thu, 20 Oct 2011 09:55:57 -0700
changeset 80377 2739199a5bbdf69e87a466d8b47f78fb796831cb
parent 80376 064189e08af2f25ff05157efce6fb61633070341
child 80378 18f70ede04b0e5be0dbcc309b4a044e2834129c5
push id434
push userclegnitto@mozilla.com
push dateWed, 21 Dec 2011 12:10:54 +0000
treeherdermozilla-beta@bddb6ed8dd47 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersUnfocused
bugs694595
milestone10.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 694595: Some settings for add-ons aren't being migrated when we change database schemas. r=Unfocused
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
@@ -2594,24 +2594,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) {
@@ -4361,17 +4367,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;
@@ -4392,16 +4402,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
@@ -154,16 +154,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]