Bug 1358846: Part 1 - Remove old database migration code. r=rhelmer

MozReview-Commit-ID: CHdKzQ2u0Rv

--HG--
extra : rebase_source : 9810c4af38aafddd4bd26f3477ec06d9c4d36f79
extra : source : 889c487a5d41926a36482270131cad200a1bfc30
This commit is contained in:
Kris Maglione 2017-04-21 18:55:12 -07:00
Родитель 6a542a8c05
Коммит c98d2b9f37
11 изменённых файлов: 8 добавлений и 1941 удалений

Просмотреть файл

@ -48,9 +48,7 @@ const nsIFile = Components.Constructor("@mozilla.org/file/local;1", "nsIFile");
var logger = Log.repository.getLogger(LOGGER_ID);
const KEY_PROFILEDIR = "ProfD";
const FILE_DATABASE = "extensions.sqlite";
const FILE_JSON_DB = "extensions.json";
const FILE_OLD_DATABASE = "extensions.rdf";
const FILE_XPI_ADDONS_LIST = "extensions.ini";
// The last version of DB_SCHEMA implemented in SQLITE
@ -69,19 +67,6 @@ const KEY_APP_SYSTEM_DEFAULTS = "app-system-defaults";
const KEY_APP_GLOBAL = "app-global";
const KEY_APP_TEMPORARY = "app-temporary";
// Properties that only exist in the database
const DB_METADATA = ["syncGUID",
"installDate",
"updateDate",
"size",
"sourceURI",
"releaseNotesURI",
"applyBackgroundUpdates"];
const DB_BOOL_METADATA = ["visible", "active", "userDisabled", "appDisabled",
"pendingUninstall", "bootstrap", "skinnable",
"softDisabled", "isForeignInstall",
"hasBinaryComponents", "strictCompatibility"];
// Properties to save in JSON file
const PROP_JSON_FIELDS = ["id", "syncGUID", "location", "version", "type",
"internalName", "updateURL", "updateKey", "optionsURL",
@ -96,59 +81,9 @@ const PROP_JSON_FIELDS = ["id", "syncGUID", "location", "version", "type",
"seen", "dependencies", "hasEmbeddedWebExtension", "mpcOptedOut",
"userPermissions", "icons", "iconURL", "icon64URL"];
// Properties that should be migrated where possible from an old database. These
// shouldn't include properties that can be read directly from install.rdf files
// or calculated
const DB_MIGRATE_METADATA = ["installDate", "userDisabled", "softDisabled",
"sourceURI", "applyBackgroundUpdates",
"releaseNotesURI", "foreignInstall", "syncGUID"];
// Time to wait before async save of XPI JSON database, in milliseconds
const ASYNC_SAVE_DELAY_MS = 20;
const PREFIX_ITEM_URI = "urn:mozilla:item:";
const RDFURI_ITEM_ROOT = "urn:mozilla:item:root"
const PREFIX_NS_EM = "http://www.mozilla.org/2004/em-rdf#";
XPCOMUtils.defineLazyServiceGetter(this, "gRDF", "@mozilla.org/rdf/rdf-service;1",
Ci.nsIRDFService);
function EM_R(aProperty) {
return gRDF.GetResource(PREFIX_NS_EM + aProperty);
}
/**
* Converts an RDF literal, resource or integer into a string.
*
* @param aLiteral
* The RDF object to convert
* @return a string if the object could be converted or null
*/
function getRDFValue(aLiteral) {
if (aLiteral instanceof Ci.nsIRDFLiteral)
return aLiteral.Value;
if (aLiteral instanceof Ci.nsIRDFResource)
return aLiteral.Value;
if (aLiteral instanceof Ci.nsIRDFInt)
return aLiteral.Value;
return null;
}
/**
* Gets an RDF property as a string
*
* @param aDs
* The RDF datasource to read the property from
* @param aResource
* The RDF resource to read the property from
* @param aProperty
* The property to read
* @return a string if the property existed or null
*/
function getRDFProperty(aDs, aResource, aProperty) {
return getRDFValue(aDs.GetTarget(aResource, EM_R(aProperty), true));
}
/**
* Asynchronously fill in the _repositoryAddon field for one addon
*/
@ -223,50 +158,6 @@ function asyncMap(aObjects, aMethod, aCallback) {
});
}
/**
* A generator to synchronously return result rows from an mozIStorageStatement.
*
* @param aStatement
* The statement to execute
*/
function* resultRows(aStatement) {
try {
while (stepStatement(aStatement))
yield aStatement.row;
} finally {
aStatement.reset();
}
}
/**
* A helper function to log an SQL error.
*
* @param aError
* The storage error code associated with the error
* @param aErrorString
* An error message
*/
function logSQLError(aError, aErrorString) {
logger.error("SQL error " + aError + ": " + aErrorString);
}
/**
* A helper function to step a statement synchronously and log any error that
* occurs.
*
* @param aStatement
* A mozIStorageStatement to execute
*/
function stepStatement(aStatement) {
try {
return aStatement.executeStep();
} catch (e) {
logSQLError(XPIDatabase.connection.lastError,
XPIDatabase.connection.lastErrorString);
throw e;
}
}
/**
* Copies properties from one object to another. If no target object is passed
* a new object will be created and returned.
@ -498,32 +389,6 @@ this.XPIDatabase = {
return toSave;
},
/**
* Pull upgrade information from an existing SQLITE database
*
* @return false if there is no SQLITE database
* true and sets this.migrateData to null if the SQLITE DB exists
* but does not contain useful information
* true and sets this.migrateData to
* {location: {id1:{addon1}, id2:{addon2}}, location2:{...}, ...}
* if there is useful information
*/
getMigrateDataFromSQLITE() {
let connection = null;
let dbfile = FileUtils.getFile(KEY_PROFILEDIR, [FILE_DATABASE], true);
// Attempt to open the database
try {
connection = Services.storage.openUnsharedDatabase(dbfile);
} catch (e) {
logger.warn("Failed to open sqlite database " + dbfile.path + " for upgrade", e);
return null;
}
logger.debug("Migrating data from sqlite");
let migrateData = this.getMigrateDataFromDatabase(connection);
connection.close();
return migrateData;
},
/**
* Synchronously opens and reads the database file, upgrading from old
* databases or making a new DB if needed.
@ -668,21 +533,12 @@ this.XPIDatabase = {
*/
upgradeDB(aRebuildOnError) {
let upgradeTimer = AddonManagerPrivate.simpleTimer("XPIDB_upgradeDB_MS");
try {
let schemaVersion = Services.prefs.getIntPref(PREF_DB_SCHEMA);
if (schemaVersion <= LAST_SQLITE_DB_SCHEMA) {
// we should have an older SQLITE database
logger.debug("Attempting to upgrade from SQLITE database");
this.migrateData = this.getMigrateDataFromSQLITE();
} else {
// we've upgraded before but the JSON file is gone, fall through
// and rebuild from scratch
AddonManagerPrivate.recordSimpleMeasure("XPIDB_startupError", "dbMissing");
}
} catch (e) {
// No schema version pref means either a really old upgrade (RDF) or
// a new profile
this.migrateData = this.getMigrateDataFromRDF();
let schemaVersion = Services.prefs.getIntPref(PREF_DB_SCHEMA, 0);
if (schemaVersion > LAST_SQLITE_DB_SCHEMA) {
// we've upgraded before but the JSON file is gone, fall through
// and rebuild from scratch
AddonManagerPrivate.recordSimpleMeasure("XPIDB_startupError", "dbMissing");
}
this.rebuildDatabase(aRebuildOnError);
@ -834,163 +690,6 @@ this.XPIDatabase = {
return bundles;
},
/**
* Retrieves migration data from the old extensions.rdf database.
*
* @return an object holding information about what add-ons were previously
* userDisabled and any updated compatibility information
*/
getMigrateDataFromRDF(aDbWasMissing) {
// Migrate data from extensions.rdf
let rdffile = FileUtils.getFile(KEY_PROFILEDIR, [FILE_OLD_DATABASE], true);
if (!rdffile.exists())
return null;
logger.debug("Migrating data from " + FILE_OLD_DATABASE);
let migrateData = {};
try {
let ds = gRDF.GetDataSourceBlocking(Services.io.newFileURI(rdffile).spec);
let root = Cc["@mozilla.org/rdf/container;1"].
createInstance(Ci.nsIRDFContainer);
root.Init(ds, gRDF.GetResource(RDFURI_ITEM_ROOT));
let elements = root.GetElements();
while (elements.hasMoreElements()) {
let source = elements.getNext().QueryInterface(Ci.nsIRDFResource);
let location = getRDFProperty(ds, source, "installLocation");
if (location) {
if (!(location in migrateData))
migrateData[location] = {};
let id = source.ValueUTF8.substring(PREFIX_ITEM_URI.length);
migrateData[location][id] = {
version: getRDFProperty(ds, source, "version"),
userDisabled: false,
targetApplications: []
}
let disabled = getRDFProperty(ds, source, "userDisabled");
if (disabled == "true" || disabled == "needs-disable")
migrateData[location][id].userDisabled = true;
let targetApps = ds.GetTargets(source, EM_R("targetApplication"),
true);
while (targetApps.hasMoreElements()) {
let targetApp = targetApps.getNext()
.QueryInterface(Ci.nsIRDFResource);
let appInfo = {
id: getRDFProperty(ds, targetApp, "id")
};
let minVersion = getRDFProperty(ds, targetApp, "updatedMinVersion");
if (minVersion) {
appInfo.minVersion = minVersion;
appInfo.maxVersion = getRDFProperty(ds, targetApp, "updatedMaxVersion");
} else {
appInfo.minVersion = getRDFProperty(ds, targetApp, "minVersion");
appInfo.maxVersion = getRDFProperty(ds, targetApp, "maxVersion");
}
migrateData[location][id].targetApplications.push(appInfo);
}
}
}
} catch (e) {
logger.warn("Error reading " + FILE_OLD_DATABASE, e);
migrateData = null;
}
return migrateData;
},
/**
* Retrieves migration data from a database that has an older or newer schema.
*
* @return an object holding information about what add-ons were previously
* userDisabled and any updated compatibility information
*/
getMigrateDataFromDatabase(aConnection) {
let migrateData = {};
// Attempt to migrate data from a different (even future!) version of the
// database
try {
var stmt = aConnection.createStatement("PRAGMA table_info(addon)");
const REQUIRED = ["internal_id", "id", "location", "userDisabled",
"installDate", "version"];
let reqCount = 0;
let props = [];
for (let row of resultRows(stmt)) {
if (REQUIRED.indexOf(row.name) != -1) {
reqCount++;
props.push(row.name);
} else if (DB_METADATA.indexOf(row.name) != -1) {
props.push(row.name);
} else if (DB_BOOL_METADATA.indexOf(row.name) != -1) {
props.push(row.name);
}
}
if (reqCount < REQUIRED.length) {
logger.error("Unable to read anything useful from the database");
return null;
}
stmt.finalize();
stmt = aConnection.createStatement("SELECT " + props.join(",") + " FROM addon");
for (let row of resultRows(stmt)) {
if (!(row.location in migrateData))
migrateData[row.location] = {};
let addonData = {
targetApplications: []
}
migrateData[row.location][row.id] = addonData;
props.forEach(function(aProp) {
if (aProp == "isForeignInstall")
addonData.foreignInstall = (row[aProp] == 1);
if (DB_BOOL_METADATA.indexOf(aProp) != -1)
addonData[aProp] = row[aProp] == 1;
else
addonData[aProp] = row[aProp];
})
}
var taStmt = aConnection.createStatement("SELECT id, minVersion, " +
"maxVersion FROM " +
"targetApplication WHERE " +
"addon_internal_id=:internal_id");
for (let location in migrateData) {
for (let id in migrateData[location]) {
taStmt.params.internal_id = migrateData[location][id].internal_id;
delete migrateData[location][id].internal_id;
for (let row of resultRows(taStmt)) {
migrateData[location][id].targetApplications.push({
id: row.id,
minVersion: row.minVersion,
maxVersion: row.maxVersion
});
}
}
}
} catch (e) {
// An error here means the schema is too different to read
logger.error("Error migrating data", e);
return null;
} finally {
if (taStmt)
taStmt.finalize();
if (stmt)
stmt.finalize();
}
return migrateData;
},
/**
* Shuts down the database connection and releases all cached objects.
* Return: Promise{integer} resolves / rejects with the result of the DB
@ -1602,20 +1301,17 @@ this.XPIDatabaseReconcile = {
* @param aOldPlatformVersion
* The version of the platform last run with this profile or null
* if it is a new profile or the version is unknown
* @param aMigrateData
* If during startup the database had to be upgraded this will
* contain data that used to be held about this add-on
* @return a boolean indicating if flushing caches is required to complete
* changing this add-on
*/
addMetadata(aInstallLocation, aId, aAddonState, aNewAddon, aOldAppVersion,
aOldPlatformVersion, aMigrateData) {
aOldPlatformVersion) {
logger.debug("New add-on " + aId + " installed in " + aInstallLocation.name);
// If we had staged data for this add-on or we aren't recovering from a
// corrupt database and we don't have migration data for this add-on then
// this must be a new install.
let isNewInstall = (!!aNewAddon) || (!XPIDatabase.activeBundles && !aMigrateData);
let isNewInstall = !!aNewAddon || !XPIDatabase.activeBundles;
// If it's a new install and we haven't yet loaded the manifest then it
// must be something dropped directly into the install location
@ -1661,38 +1357,6 @@ this.XPIDatabaseReconcile = {
// appDisabled depends on whether the add-on is a foreignInstall so update
aNewAddon.appDisabled = !isUsableAddon(aNewAddon);
if (aMigrateData) {
// If there is migration data then apply it.
logger.debug("Migrating data from old database");
DB_MIGRATE_METADATA.forEach(function(aProp) {
// A theme's disabled state is determined by the selected theme
// preference which is read in loadManifestFromRDF
if (aProp == "userDisabled" && aNewAddon.type == "theme")
return;
if (aProp in aMigrateData)
aNewAddon[aProp] = aMigrateData[aProp];
});
// Force all non-profile add-ons to be foreignInstalls since they can't
// have been installed through the API
aNewAddon.foreignInstall |= aInstallLocation.name != KEY_APP_PROFILE;
// 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 == aNewAddon.version) {
logger.debug("Migrating compatibility info");
if ("targetApplications" in aMigrateData)
aNewAddon.applyCompatibilityUpdate(aMigrateData, true);
}
// Since the DB schema has changed make sure softDisabled is correct
applyBlocklistChanges(aNewAddon, aNewAddon, aOldAppVersion,
aOldPlatformVersion);
}
// The default theme is never a foreign install
if (aNewAddon.type == "theme" && aNewAddon.internalName == XPIProvider.defaultSkin)
aNewAddon.foreignInstall = false;

Просмотреть файл

@ -1,125 +0,0 @@
<?xml version="1.0"?>
<!-- This is a copy of extensions.rdf from Firefox 3.5 including four
test extensions. Addon1 was user enabled, addon2 was user disabled, addon3
was pending user disable at the next restart and addon4 was pending user
enable at the next restart. Additionally addon1 and 2 have had
compatibility updates applies to make them compatible with the app and
toolkit respectively, addon3 and 4 have not. addon5 is disabled however
at the same time as the migration a new version should be detected. addon6
is pending install and needs a compatibility update to be compatible.
It also contains two themes in the profile -->
<RDF:RDF xmlns:NS1="http://www.mozilla.org/2004/em-rdf#"
xmlns:NC="http://home.netscape.com/NC-rdf#"
xmlns:RDF="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
<RDF:Description RDF:about="rdf:#$w8dNC3"
NS1:id="xpcshell@tests.mozilla.org"
NS1:minVersion="1"
NS1:maxVersion="1" />
<RDF:Description RDF:about="rdf:#$w8dNC4"
NS1:id="xpcshell@tests.mozilla.org"
NS1:minVersion="1"
NS1:maxVersion="2" />
<RDF:Description RDF:about="rdf:#$w8dNC5"
NS1:id="xpcshell@tests.mozilla.org"
NS1:minVersion="1"
NS1:maxVersion="2" />
<RDF:Description RDF:about="rdf:#$w8dNC6"
NS1:id="xpcshell@tests.mozilla.org"
NS1:minVersion="1"
NS1:maxVersion="2" />
<RDF:Description RDF:about="rdf:#$w8dNC2"
NS1:id="toolkit@mozilla.org"
NS1:minVersion="1"
NS1:maxVersion="1" />
<RDF:Description RDF:about="rdf:#$w8dNC1"
NS1:id="toolkit@mozilla.org"
NS1:minVersion="1"
NS1:maxVersion="2" />
<RDF:Description RDF:about="rdf:#$w8dNC7"
NS1:id="toolkit@mozilla.org"
NS1:minVersion="1"
NS1:maxVersion="2" />
<RDF:Description RDF:about="rdf:#$oadNC1"
NS1:id="xpcshell@tests.mozilla.org"
NS1:minVersion="1"
NS1:maxVersion="2" />
<RDF:Description RDF:about="rdf:#$TpnM4"
NS1:id="xpcshell@tests.mozilla.org"
NS1:updatedMinVersion="1"
NS1:updatedMaxVersion="2" />
<RDF:Description RDF:about="urn:mozilla:item:addon1@tests.mozilla.org"
NS1:installLocation="app-profile"
NS1:version="1.0"
NS1:name="Test 1">
<NS1:type NC:parseType="Integer">2</NS1:type>
<NS1:targetApplication RDF:resource="rdf:#$oadNC1"/>
</RDF:Description>
<RDF:Description RDF:about="urn:mozilla:item:addon2@tests.mozilla.org"
NS1:installLocation="app-profile"
NS1:version="2.0"
NS1:name="Test 2"
NS1:userDisabled="true">
<NS1:type NC:parseType="Integer">2</NS1:type>
<NS1:targetApplication RDF:resource="rdf:#$w8dNC1"/>
</RDF:Description>
<RDF:Description RDF:about="urn:mozilla:item:addon3@tests.mozilla.org"
NS1:installLocation="app-profile"
NS1:version="2.0"
NS1:name="Test 3"
NS1:userDisabled="needs-disable">
<NS1:type NC:parseType="Integer">2</NS1:type>
<NS1:targetApplication RDF:resource="rdf:#$w8dNC3"/>
</RDF:Description>
<RDF:Description RDF:about="urn:mozilla:item:addon4@tests.mozilla.org"
NS1:installLocation="app-profile"
NS1:version="2.0"
NS1:name="Test 4"
NS1:userDisabled="needs-enable">
<NS1:type NC:parseType="Integer">2</NS1:type>
<NS1:targetApplication RDF:resource="rdf:#$w8dNC2"/>
</RDF:Description>
<RDF:Description RDF:about="urn:mozilla:item:addon5@tests.mozilla.org"
NS1:installLocation="app-profile"
NS1:version="1.0"
NS1:name="Test 5"
NS1:userDisabled="true">
<NS1:type NC:parseType="Integer">2</NS1:type>
<NS1:targetApplication RDF:resource="rdf:#$w8dNC7"/>
</RDF:Description>
<RDF:Description RDF:about="urn:mozilla:item:addon6@tests.mozilla.org"
NS1:name="Test 6"
NS1:version="1.0"
NS1:newVersion="1.0"
NS1:installLocation="app-profile">
<NS1:type NC:parseType="Integer">2</NS1:type>
<NS1:targetApplication RDF:resource="rdf:#$TpnM4"/>
</RDF:Description>
<RDF:Description RDF:about="urn:mozilla:item:theme1@tests.mozilla.org"
NS1:installLocation="app-profile"
NS1:version="1.0"
NS1:name="Theme 2"
NS1:internalName="theme1/1.0">
<NS1:type NC:parseType="Integer">4</NS1:type>
<NS1:targetApplication RDF:resource="rdf:#$w8dNC5"/>
</RDF:Description>
<RDF:Description RDF:about="urn:mozilla:item:theme2@tests.mozilla.org"
NS1:installLocation="app-profile"
NS1:version="2.0"
NS1:name="Theme 2"
NS1:internalName="theme2/1.0">
<NS1:type NC:parseType="Integer">4</NS1:type>
<NS1:targetApplication RDF:resource="rdf:#$w8dNC6"/>
</RDF:Description>
<RDF:Seq RDF:about="urn:mozilla:item:root">
<RDF:li RDF:resource="urn:mozilla:item:addon1@tests.mozilla.org"/>
<RDF:li RDF:resource="urn:mozilla:item:addon2@tests.mozilla.org"/>
<RDF:li RDF:resource="urn:mozilla:item:addon3@tests.mozilla.org"/>
<RDF:li RDF:resource="urn:mozilla:item:addon4@tests.mozilla.org"/>
<RDF:li RDF:resource="urn:mozilla:item:addon5@tests.mozilla.org"/>
<RDF:li RDF:resource="urn:mozilla:item:addon6@tests.mozilla.org"/>
<RDF:li RDF:resource="urn:mozilla:item:theme1@tests.mozilla.org"/>
<RDF:li RDF:resource="urn:mozilla:item:theme2@tests.mozilla.org"/>
</RDF:Seq>
</RDF:RDF>

Просмотреть файл

@ -1,46 +0,0 @@
<?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:%PORT%/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>

Просмотреть файл

@ -1,231 +0,0 @@
/* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/publicdomain/zero/1.0/
*/
// 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",
maxVersion: "1"
}]
};
var addon2 = {
id: "addon2@tests.mozilla.org",
version: "2.0",
name: "Test 2",
targetApplications: [{
id: "toolkit@mozilla.org",
minVersion: "1",
maxVersion: "1"
}]
};
var addon3 = {
id: "addon3@tests.mozilla.org",
version: "2.0",
name: "Test 3",
targetApplications: [{
id: "xpcshell@tests.mozilla.org",
minVersion: "1",
maxVersion: "1"
}]
};
var addon4 = {
id: "addon4@tests.mozilla.org",
version: "2.0",
name: "Test 4",
targetApplications: [{
id: "toolkit@mozilla.org",
minVersion: "1",
maxVersion: "1"
}]
};
var addon5 = {
id: "addon5@tests.mozilla.org",
version: "2.0",
name: "Test 5",
targetApplications: [{
id: "toolkit@mozilla.org",
minVersion: "1",
maxVersion: "1"
}]
};
var theme1 = {
id: "theme1@tests.mozilla.org",
version: "1.0",
name: "Theme 1",
type: 4,
internalName: "theme1/1.0",
targetApplications: [{
id: "xpcshell@tests.mozilla.org",
minVersion: "1",
maxVersion: "2"
}]
};
var theme2 = {
id: "theme2@tests.mozilla.org",
version: "1.0",
name: "Theme 2",
type: 4,
internalName: "theme2/1.0",
targetApplications: [{
id: "xpcshell@tests.mozilla.org",
minVersion: "1",
maxVersion: "2"
}]
};
const profileDir = gProfD.clone();
profileDir.append("extensions");
function run_test() {
do_test_pending();
createAppInfo("xpcshell@tests.mozilla.org", "XPCShell", "2", "2");
writeInstallRDFForExtension(addon1, profileDir);
writeInstallRDFForExtension(addon2, profileDir);
writeInstallRDFForExtension(addon3, profileDir);
writeInstallRDFForExtension(addon4, profileDir);
writeInstallRDFForExtension(addon5, profileDir);
writeInstallRDFForExtension(theme1, profileDir);
writeInstallRDFForExtension(theme2, profileDir);
let stagedXPIs = profileDir.clone();
stagedXPIs.append("staged-xpis");
stagedXPIs.append("addon6@tests.mozilla.org");
stagedXPIs.create(AM_Ci.nsIFile.DIRECTORY_TYPE, FileUtils.PERMS_DIRECTORY);
let addon6 = do_get_addon("test_migrate6");
addon6.copyTo(stagedXPIs, "tmp.xpi");
stagedXPIs = stagedXPIs.parent;
stagedXPIs.append("addon7@tests.mozilla.org");
stagedXPIs.create(AM_Ci.nsIFile.DIRECTORY_TYPE, FileUtils.PERMS_DIRECTORY);
let addon7 = do_get_addon("test_migrate7");
addon7.copyTo(stagedXPIs, "tmp.xpi");
stagedXPIs = stagedXPIs.parent;
stagedXPIs.append("addon8@tests.mozilla.org");
stagedXPIs.create(AM_Ci.nsIFile.DIRECTORY_TYPE, FileUtils.PERMS_DIRECTORY);
let addon8 = do_get_addon("test_migrate8");
addon8.copyTo(stagedXPIs, "tmp.xpi");
stagedXPIs = stagedXPIs.parent;
let old = do_get_file("data/test_migrate.rdf");
old.copyTo(gProfD, "extensions.rdf");
let oldCache = gProfD.clone();
oldCache.append("extensions.cache");
oldCache.create(AM_Ci.nsIFile.NORMAL_FILE_TYPE, FileUtils.PERMS_FILE);
// Theme state is determined by the selected theme pref
Services.prefs.setCharPref("general.skins.selectedSkin", "theme1/1.0");
Services.prefs.setCharPref("extensions.lastAppVersion", "1");
startupManager();
check_startup_changes("installed", []);
check_startup_changes("updated", []);
check_startup_changes("uninstalled", []);
check_startup_changes("disabled", []);
check_startup_changes("enabled", []);
do_check_false(oldCache.exists());
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",
"addon7@tests.mozilla.org",
"addon8@tests.mozilla.org",
"theme1@tests.mozilla.org",
"theme2@tests.mozilla.org"], function([a1, a2, a3,
a4, a5, a6,
a7, a8, t1,
t2]) {
// addon1 was user and app enabled in the old extensions.rdf
do_check_neq(a1, null);
do_check_false(a1.userDisabled);
do_check_false(a1.appDisabled);
do_check_true(a1.isActive);
do_check_true(isExtensionInAddonsList(profileDir, a1.id));
do_check_false(a1.hasBinaryComponents);
do_check_true(a1.seen);
// addon2 was user disabled and app enabled in the old extensions.rdf
do_check_neq(a2, null);
do_check_true(a2.userDisabled);
do_check_false(a2.appDisabled);
do_check_false(a2.isActive);
do_check_false(isExtensionInAddonsList(profileDir, a2.id));
do_check_false(a2.hasBinaryComponents);
do_check_true(a2.seen);
// addon3 was pending user disable and app disabled in the old extensions.rdf
do_check_neq(a3, null);
do_check_true(a3.userDisabled);
do_check_true(a3.appDisabled);
do_check_false(a3.isActive);
do_check_false(isExtensionInAddonsList(profileDir, a3.id));
do_check_false(a3.hasBinaryComponents);
do_check_true(a3.seen);
// addon4 was pending user enable and app disabled in the old extensions.rdf
do_check_neq(a4, null);
do_check_false(a4.userDisabled);
do_check_true(a4.appDisabled);
do_check_false(a4.isActive);
do_check_false(isExtensionInAddonsList(profileDir, a4.id));
do_check_false(a4.hasBinaryComponents);
do_check_true(a4.seen);
// addon5 was disabled and compatible but a new version has been installed
// since, it should still be disabled but should be incompatible
do_check_neq(a5, null);
do_check_true(a5.userDisabled);
do_check_true(a5.appDisabled);
do_check_false(a5.isActive);
do_check_false(isExtensionInAddonsList(profileDir, a5.id));
do_check_false(a5.hasBinaryComponents);
do_check_true(a5.seen);
// addon6, addon7 and addon8 will have been lost as they were staged in the
// pre-Firefox 4.0 directory
do_check_eq(a6, null);
do_check_eq(a7, null);
do_check_eq(a8, null);
// Theme 1 was previously enabled
do_check_neq(t1, null);
do_check_false(t1.userDisabled);
do_check_false(t1.appDisabled);
do_check_true(t1.isActive);
do_check_true(isThemeInAddonsList(profileDir, t1.id));
do_check_false(hasFlag(t1.permissions, AddonManager.PERM_CAN_ENABLE));
do_check_true(t1.seen);
// Theme 2 was previously disabled
do_check_neq(t2, null);
do_check_true(t2.userDisabled);
do_check_false(t2.appDisabled);
do_check_false(t2.isActive);
do_check_false(isThemeInAddonsList(profileDir, t2.id));
do_check_true(hasFlag(t2.permissions, AddonManager.PERM_CAN_ENABLE));
do_check_true(t2.seen);
do_execute_soon(do_test_finished);
});
}

Просмотреть файл

@ -1,267 +0,0 @@
/* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/publicdomain/zero/1.0/
*/
// Checks that we migrate data from SQLITE databases
// Note that since the database doesn't contain the foreignInstall field we
// should just assume that no add-ons in the user profile were foreignInstalls
// Enable loading extensions from the user and system scopes
Services.prefs.setIntPref("extensions.enabledScopes",
AddonManager.SCOPE_PROFILE + AddonManager.SCOPE_USER +
AddonManager.SCOPE_SYSTEM);
var addon1 = {
id: "addon1@tests.mozilla.org",
version: "1.0",
name: "Test 1",
targetApplications: [{
id: "xpcshell@tests.mozilla.org",
minVersion: "1",
maxVersion: "1"
}]
};
var addon2 = {
id: "addon2@tests.mozilla.org",
version: "2.0",
name: "Test 2",
targetApplications: [{
id: "xpcshell@tests.mozilla.org",
minVersion: "1",
maxVersion: "1"
}]
};
var addon3 = {
id: "addon3@tests.mozilla.org",
version: "2.0",
name: "Test 3",
targetApplications: [{
id: "xpcshell@tests.mozilla.org",
minVersion: "1",
maxVersion: "1"
}]
};
var addon4 = {
id: "addon4@tests.mozilla.org",
version: "2.0",
name: "Test 4",
strictCompatibility: true,
targetApplications: [{
id: "xpcshell@tests.mozilla.org",
minVersion: "1",
maxVersion: "1"
}]
};
var addon5 = {
id: "addon5@tests.mozilla.org",
version: "2.0",
name: "Test 5",
targetApplications: [{
id: "xpcshell@tests.mozilla.org",
minVersion: "0",
maxVersion: "0"
}]
};
var addon6 = {
id: "addon6@tests.mozilla.org",
version: "2.0",
name: "Test 6",
targetApplications: [{
id: "xpcshell@tests.mozilla.org",
minVersion: "0",
maxVersion: "0"
}]
};
var addon7 = {
id: "addon7@tests.mozilla.org",
version: "2.0",
name: "Test 7",
targetApplications: [{
id: "xpcshell@tests.mozilla.org",
minVersion: "1",
maxVersion: "1"
}]
};
var addon8 = {
id: "addon8@tests.mozilla.org",
version: "2.0",
name: "Test 8",
targetApplications: [{
id: "xpcshell@tests.mozilla.org",
minVersion: "1",
maxVersion: "1"
}]
};
createAppInfo("xpcshell@tests.mozilla.org", "XPCShell", "1", "1.9.2");
const profileDir = gProfD.clone();
profileDir.append("extensions");
const globalDir = gProfD.clone();
globalDir.append("extensions2");
globalDir.append(gAppInfo.ID);
registerDirectory("XRESysSExtPD", globalDir.parent);
const userDir = gProfD.clone();
userDir.append("extensions3");
userDir.append(gAppInfo.ID);
registerDirectory("XREUSysExt", userDir.parent);
function run_test() {
do_test_pending();
writeInstallRDFForExtension(addon1, profileDir);
writeInstallRDFForExtension(addon2, profileDir);
writeInstallRDFForExtension(addon3, profileDir);
writeInstallRDFForExtension(addon4, profileDir);
writeInstallRDFForExtension(addon5, profileDir);
writeInstallRDFForExtension(addon6, profileDir);
writeInstallRDFForExtension(addon7, globalDir);
writeInstallRDFForExtension(addon8, userDir);
// Write out a minimal database
let dbfile = gProfD.clone();
dbfile.append("extensions.sqlite");
let db = AM_Cc["@mozilla.org/storage/service;1"].
getService(AM_Ci.mozIStorageService).
openDatabase(dbfile);
db.createTable("addon", "internal_id INTEGER PRIMARY KEY AUTOINCREMENT, " +
"id TEXT, location TEXT, version TEXT, active INTEGER, " +
"userDisabled INTEGER, installDate INTEGER");
db.createTable("targetApplication", "addon_internal_id INTEGER, " +
"id TEXT, minVersion TEXT, maxVersion TEXT");
let stmt = db.createStatement("INSERT INTO addon VALUES (NULL, :id, :location, " +
":version, :active, :userDisabled, :installDate)");
let internal_ids = {};
[["addon1@tests.mozilla.org", "app-profile", "1.0", "1", "0", "0"],
["addon2@tests.mozilla.org", "app-profile", "2.0", "0", "1", "0"],
["addon3@tests.mozilla.org", "app-profile", "2.0", "1", "1", "0"],
["addon4@tests.mozilla.org", "app-profile", "2.0", "0", "0", "0"],
["addon5@tests.mozilla.org", "app-profile", "2.0", "1", "0", "0"],
["addon6@tests.mozilla.org", "app-profile", "1.0", "0", "1", "0"],
["addon7@tests.mozilla.org", "app-system-share", "1.0", "1", "0", "0"],
["addon8@tests.mozilla.org", "app-system-user", "1.0", "1", "0", "0"]].forEach(function(a) {
stmt.params.id = a[0];
stmt.params.location = a[1];
stmt.params.version = a[2];
stmt.params.active = a[3];
stmt.params.userDisabled = a[4];
stmt.params.installDate = a[5];
stmt.execute();
internal_ids[a[0]] = db.lastInsertRowID;
});
stmt.finalize();
// Add updated target application into for addon5
stmt = db.createStatement("INSERT INTO targetApplication VALUES " +
"(:internal_id, :id, :minVersion, :maxVersion)");
stmt.params.internal_id = internal_ids["addon5@tests.mozilla.org"];
stmt.params.id = "xpcshell@tests.mozilla.org";
stmt.params.minVersion = "0";
stmt.params.maxVersion = "1";
stmt.execute();
// Add updated target application into for addon6
stmt.params.internal_id = internal_ids["addon6@tests.mozilla.org"];
stmt.params.id = "xpcshell@tests.mozilla.org";
stmt.params.minVersion = "0";
stmt.params.maxVersion = "1";
stmt.execute();
stmt.finalize();
db.schemaVersion = 10000;
Services.prefs.setIntPref("extensions.databaseSchema", 14);
db.close();
startupManager();
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",
"addon7@tests.mozilla.org",
"addon8@tests.mozilla.org"],
function([a1, a2, a3, a4, a5, a6, a7, a8]) {
// addon1 was enabled in the database
do_check_neq(a1, null);
do_check_false(a1.userDisabled);
do_check_false(a1.appDisabled);
do_check_true(a1.isActive);
do_check_false(a1.strictCompatibility);
do_check_false(a1.foreignInstall);
do_check_true(a1.seen);
// addon2 was disabled in the database
do_check_neq(a2, null);
do_check_true(a2.userDisabled);
do_check_false(a2.appDisabled);
do_check_false(a2.isActive);
do_check_false(a2.strictCompatibility);
do_check_false(a2.foreignInstall);
do_check_true(a2.seen);
// 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_false(a3.strictCompatibility);
do_check_false(a3.foreignInstall);
do_check_true(a3.seen);
// 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.strictCompatibility);
do_check_false(a4.foreignInstall);
do_check_true(a4.seen);
// addon5 was enabled in the database but needed a compatibility update
do_check_neq(a5, null);
do_check_false(a5.userDisabled);
do_check_false(a5.appDisabled);
do_check_true(a5.isActive);
do_check_false(a5.strictCompatibility);
do_check_false(a5.foreignInstall);
do_check_true(a5.seen);
// 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_check_false(a6.strictCompatibility);
do_check_false(a6.foreignInstall);
do_check_true(a6.seen);
// addon7 is in the global install location so should be a foreignInstall
do_check_neq(a7, null);
do_check_false(a7.userDisabled);
do_check_false(a7.appDisabled);
do_check_true(a7.isActive);
do_check_false(a7.strictCompatibility);
do_check_true(a7.foreignInstall);
do_check_true(a7.seen);
// addon8 is in the user install location so should be a foreignInstall
do_check_neq(a8, null);
do_check_false(a8.userDisabled);
do_check_false(a8.appDisabled);
do_check_true(a8.isActive);
do_check_false(a8.strictCompatibility);
do_check_true(a8.foreignInstall);
do_check_true(a8.seen);
do_execute_soon(do_test_finished);
});
}

Просмотреть файл

@ -1,229 +0,0 @@
/* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/publicdomain/zero/1.0/
*/
// 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",
name: "Test 1",
targetApplications: [{
id: "xpcshell@tests.mozilla.org",
minVersion: "1",
maxVersion: "1"
}]
};
var addon2 = {
id: "addon2@tests.mozilla.org",
version: "2.0",
name: "Test 2",
targetApplications: [{
id: "toolkit@mozilla.org",
minVersion: "1",
maxVersion: "1"
}]
};
var addon3 = {
id: "addon3@tests.mozilla.org",
version: "2.0",
name: "Test 3",
targetApplications: [{
id: "xpcshell@tests.mozilla.org",
minVersion: "1",
maxVersion: "1"
}]
};
var addon4 = {
id: "addon4@tests.mozilla.org",
version: "2.0",
name: "Test 4",
targetApplications: [{
id: "toolkit@mozilla.org",
minVersion: "1",
maxVersion: "1"
}]
};
var addon5 = {
id: "addon5@tests.mozilla.org",
version: "2.0",
name: "Test 5",
targetApplications: [{
id: "toolkit@mozilla.org",
minVersion: "1",
maxVersion: "1"
}]
};
var theme1 = {
id: "theme1@tests.mozilla.org",
version: "1.0",
name: "Theme 1",
type: 4,
internalName: "theme1/1.0",
targetApplications: [{
id: "xpcshell@tests.mozilla.org",
minVersion: "1",
maxVersion: "2"
}]
};
var theme2 = {
id: "theme2@tests.mozilla.org",
version: "1.0",
name: "Theme 2",
type: 4,
internalName: "theme2/1.0",
targetApplications: [{
id: "xpcshell@tests.mozilla.org",
minVersion: "1",
maxVersion: "2"
}]
};
const profileDir = gProfD.clone();
profileDir.append("extensions");
function run_test() {
do_test_pending();
createAppInfo("xpcshell@tests.mozilla.org", "XPCShell", "2", "2");
writeInstallRDFForExtension(addon1, profileDir);
writeInstallRDFForExtension(addon2, profileDir);
writeInstallRDFForExtension(addon3, profileDir);
writeInstallRDFForExtension(addon4, profileDir);
writeInstallRDFForExtension(addon5, profileDir);
writeInstallRDFForExtension(theme1, profileDir);
writeInstallRDFForExtension(theme2, profileDir);
// Cannot use the LightweightThemeManager before AddonManager has been started
// so inject the correct prefs
Services.prefs.setCharPref("lightweightThemes.usedThemes", JSON.stringify([{
id: "1",
version: "1",
name: "Test LW Theme",
description: "A test theme",
author: "Mozilla",
homepageURL: "http://localhost/data/index.html",
headerURL: "http://localhost/data/header.png",
footerURL: "http://localhost/data/footer.png",
previewURL: "http://localhost/data/preview.png",
iconURL: "http://localhost/data/icon.png"
}]));
Services.prefs.setCharPref("lightweightThemes.selectedThemeID", "1");
let stagedXPIs = profileDir.clone();
stagedXPIs.append("staged-xpis");
stagedXPIs.append("addon6@tests.mozilla.org");
stagedXPIs.create(AM_Ci.nsIFile.DIRECTORY_TYPE, 0o755);
let addon6 = do_get_addon("test_migrate6");
addon6.copyTo(stagedXPIs, "tmp.xpi");
stagedXPIs = stagedXPIs.parent;
stagedXPIs.append("addon7@tests.mozilla.org");
stagedXPIs.create(AM_Ci.nsIFile.DIRECTORY_TYPE, 0o755);
let addon7 = do_get_addon("test_migrate7");
addon7.copyTo(stagedXPIs, "tmp.xpi");
stagedXPIs = stagedXPIs.parent;
let old = do_get_file("data/test_migrate.rdf");
old.copyTo(gProfD, "extensions.rdf");
// Theme state is determined by the selected theme pref
Services.prefs.setCharPref("general.skins.selectedSkin", "theme1/1.0");
startupManager();
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",
"addon7@tests.mozilla.org",
"theme1@tests.mozilla.org",
"theme2@tests.mozilla.org"], function([a1, a2, a3,
a4, a5, a6,
a7, t1, t2]) {
// addon1 was user and app enabled in the old extensions.rdf
do_check_neq(a1, null);
do_check_false(a1.userDisabled);
do_check_false(a1.appDisabled);
do_check_true(a1.isActive);
do_check_true(isExtensionInAddonsList(profileDir, a1.id));
do_check_true(a1.seen);
// addon2 was user disabled and app enabled in the old extensions.rdf
do_check_neq(a2, null);
do_check_true(a2.userDisabled);
do_check_false(a2.appDisabled);
do_check_false(a2.isActive);
do_check_false(isExtensionInAddonsList(profileDir, a2.id));
do_check_true(a2.seen);
// addon3 was pending user disable and app disabled in the old extensions.rdf
do_check_neq(a3, null);
do_check_true(a3.userDisabled);
do_check_true(a3.appDisabled);
do_check_false(a3.isActive);
do_check_false(isExtensionInAddonsList(profileDir, a3.id));
do_check_true(a3.seen);
// addon4 was pending user enable and app disabled in the old extensions.rdf
do_check_neq(a4, null);
do_check_false(a4.userDisabled);
do_check_true(a4.appDisabled);
do_check_false(a4.isActive);
do_check_false(isExtensionInAddonsList(profileDir, a4.id));
do_check_true(a4.seen);
// addon5 was disabled and compatible but a new version has been installed
// since, it should still be disabled but should be incompatible
do_check_neq(a5, null);
do_check_true(a5.userDisabled);
do_check_true(a5.appDisabled);
do_check_false(a5.isActive);
do_check_false(isExtensionInAddonsList(profileDir, a5.id));
do_check_true(a5.seen);
// addon6 and addon7 will have been lost as they were staged in the
// pre-Firefox 4.0 directory
do_check_eq(a6, null);
do_check_eq(a7, null);
// Theme 1 was previously disabled
do_check_neq(t1, null);
do_check_true(t1.userDisabled);
do_check_false(t1.appDisabled);
do_check_false(t1.isActive);
do_check_true(isThemeInAddonsList(profileDir, t1.id));
do_check_true(hasFlag(t1.permissions, AddonManager.PERM_CAN_ENABLE));
do_check_true(t1.seen);
// Theme 2 was previously disabled
do_check_neq(t2, null);
do_check_true(t2.userDisabled);
do_check_false(t2.appDisabled);
do_check_false(t2.isActive);
do_check_false(isThemeInAddonsList(profileDir, t2.id));
do_check_true(hasFlag(t2.permissions, AddonManager.PERM_CAN_ENABLE));
do_check_true(t2.seen);
do_execute_soon(do_test_finished);
});
}

Просмотреть файл

@ -1,321 +0,0 @@
/* 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 JSON database
// The test extension uses an insecure update url.
Services.prefs.setBoolPref("extensions.checkUpdateSecurity", false);
Components.utils.import("resource://testing-common/httpd.js");
var testserver = new HttpServer();
testserver.start(-1);
gPort = testserver.identity.primaryPort;
mapFile("/data/test_migrate4.rdf", testserver);
testserver.registerDirectory("/addons/", do_get_file("addons"));
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",
strictCompatibility: true,
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:" + gPort + "/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:" + gPort + "/data/test_migrate4.rdf",
targetApplications: [{
id: "xpcshell@tests.mozilla.org",
minVersion: "0",
maxVersion: "1"
}]
};
var defaultTheme = {
id: "default@tests.mozilla.org",
version: "1.0",
name: "Default",
internalName: "classic/1.0",
targetApplications: [{
id: "xpcshell@tests.mozilla.org",
minVersion: "1",
maxVersion: "2"
}]
};
const profileDir = gProfD.clone();
profileDir.append("extensions");
var oldSyncGUIDs = {};
function prepare_profile() {
createAppInfo("xpcshell@tests.mozilla.org", "XPCShell", "1", "1.9.2");
writeInstallRDFForExtension(addon1, profileDir);
writeInstallRDFForExtension(addon2, profileDir);
writeInstallRDFForExtension(addon3, profileDir);
writeInstallRDFForExtension(addon4, profileDir);
writeInstallRDFForExtension(addon5, profileDir);
writeInstallRDFForExtension(addon6, profileDir);
writeInstallRDFForExtension(defaultTheme, profileDir);
startupManager();
installAllFiles([do_get_addon("test_migrate8"), do_get_addon("test_migrate9")],
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",
"addon9@tests.mozilla.org"],
function([a1, a2, a3, a4, a5, a6, a9]) {
a1.applyBackgroundUpdates = AddonManager.AUTOUPDATE_DEFAULT;
a2.userDisabled = true;
a2.applyBackgroundUpdates = AddonManager.AUTOUPDATE_DISABLE;
a3.applyBackgroundUpdates = AddonManager.AUTOUPDATE_ENABLE;
a4.userDisabled = true;
a6.userDisabled = true;
a9.userDisabled = false;
for (let addon of [a1, a2, a3, a4, a5, a6]) {
oldSyncGUIDs[addon.id] = addon.syncGUID;
}
a6.findUpdates({
onUpdateAvailable(aAddon, aInstall6) {
AddonManager.getInstallForURL("http://localhost:" + gPort + "/addons/test_migrate4_7.xpi", function(aInstall7) {
completeAllInstalls([aInstall6, aInstall7], 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_2, a2_2, a3_2, a4_2, a5_2, a6_2]) {
a3_2.userDisabled = true;
a4_2.userDisabled = false;
a5_2.findUpdates({
onUpdateFinished() {
do_execute_soon(perform_migration);
}
}, AddonManager.UPDATE_WHEN_USER_REQUESTED);
});
});
}, "application/x-xpinstall");
}
}, AddonManager.UPDATE_WHEN_USER_REQUESTED);
});
});
}
function perform_migration() {
shutdownManager();
// Turn on disabling for all scopes
Services.prefs.setIntPref("extensions.autoDisableScopes", 15);
changeXPIDBVersion(1, data => {
// Delete the seen property from all add-ons to make sure it defaults to true
for (let addon of data.addons) {
delete addon.seen;
}
});
Services.prefs.setIntPref("extensions.databaseSchema", 1);
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",
"addon7@tests.mozilla.org",
"addon8@tests.mozilla.org",
"addon9@tests.mozilla.org"],
function([a1, a2, a3, a4, a5, a6, a7, a8, a9]) {
// addon1 was enabled
do_check_neq(a1, null);
do_check_eq(a1.syncGUID, oldSyncGUIDs[a1.id]);
do_check_false(a1.userDisabled);
do_check_false(a1.appDisabled);
do_check_true(a1.isActive);
do_check_eq(a1.applyBackgroundUpdates, AddonManager.AUTOUPDATE_DEFAULT);
do_check_true(a1.foreignInstall);
do_check_true(a1.seen);
do_check_false(a1.hasBinaryComponents);
do_check_false(a1.strictCompatibility);
// addon2 was disabled
do_check_neq(a2, null);
do_check_eq(a2.syncGUID, oldSyncGUIDs[a2.id]);
do_check_true(a2.userDisabled);
do_check_false(a2.appDisabled);
do_check_false(a2.isActive);
do_check_eq(a2.applyBackgroundUpdates, AddonManager.AUTOUPDATE_DISABLE);
do_check_true(a2.foreignInstall);
do_check_true(a2.seen);
do_check_false(a2.hasBinaryComponents);
do_check_false(a2.strictCompatibility);
// addon3 was pending-disable in the database
do_check_neq(a3, null);
do_check_eq(a3.syncGUID, oldSyncGUIDs[a3.id]);
do_check_true(a3.userDisabled);
do_check_false(a3.appDisabled);
do_check_false(a3.isActive);
do_check_eq(a3.applyBackgroundUpdates, AddonManager.AUTOUPDATE_ENABLE);
do_check_true(a3.foreignInstall);
do_check_true(a3.seen);
do_check_false(a3.hasBinaryComponents);
do_check_false(a3.strictCompatibility);
// addon4 was pending-enable in the database
do_check_neq(a4, null);
do_check_eq(a4.syncGUID, oldSyncGUIDs[a4.id]);
do_check_false(a4.userDisabled);
do_check_false(a4.appDisabled);
do_check_true(a4.isActive);
do_check_eq(a4.applyBackgroundUpdates, AddonManager.AUTOUPDATE_DEFAULT);
do_check_true(a4.foreignInstall);
do_check_true(a4.seen);
do_check_false(a4.hasBinaryComponents);
do_check_true(a4.strictCompatibility);
// addon5 was enabled in the database but needed a compatibility update
do_check_neq(a5, null);
do_check_false(a5.userDisabled);
do_check_false(a5.appDisabled);
do_check_true(a5.isActive);
do_check_eq(a4.applyBackgroundUpdates, AddonManager.AUTOUPDATE_DEFAULT);
do_check_true(a5.foreignInstall);
do_check_true(a5.seen);
do_check_false(a5.hasBinaryComponents);
do_check_false(a5.strictCompatibility);
// addon6 was disabled and compatible but a new version has been installed
do_check_neq(a6, null);
do_check_eq(a6.syncGUID, oldSyncGUIDs[a6.id]);
do_check_eq(a6.version, "2.0");
do_check_true(a6.userDisabled);
do_check_false(a6.appDisabled);
do_check_false(a6.isActive);
do_check_eq(a6.applyBackgroundUpdates, AddonManager.AUTOUPDATE_DEFAULT);
do_check_true(a6.foreignInstall);
do_check_true(a6.seen);
do_check_eq(a6.sourceURI.spec, "http://localhost:" + gPort + "/addons/test_migrate4_6.xpi");
do_check_eq(a6.releaseNotesURI.spec, "http://example.com/updateInfo.xhtml");
do_check_false(a6.hasBinaryComponents);
do_check_false(a6.strictCompatibility);
// addon7 was installed manually
do_check_neq(a7, null);
do_check_eq(a7.version, "1.0");
do_check_false(a7.userDisabled);
do_check_false(a7.appDisabled);
do_check_true(a7.isActive);
do_check_eq(a7.applyBackgroundUpdates, AddonManager.AUTOUPDATE_DEFAULT);
do_check_false(a7.foreignInstall);
do_check_true(a7.seen);
do_check_eq(a7.sourceURI.spec, "http://localhost:" + gPort + "/addons/test_migrate4_7.xpi");
do_check_eq(a7.releaseNotesURI, null);
do_check_false(a7.hasBinaryComponents);
do_check_false(a7.strictCompatibility);
// addon8 was enabled and has binary components
do_check_neq(a8, null);
do_check_false(a8.userDisabled);
do_check_false(a8.appDisabled);
do_check_true(a8.isActive);
do_check_false(a8.foreignInstall);
do_check_true(a8.seen);
do_check_true(a8.hasBinaryComponents);
do_check_false(a8.strictCompatibility);
// addon9 is the active theme
do_check_neq(a9, null);
do_check_false(a9.userDisabled);
do_check_false(a9.appDisabled);
do_check_true(a9.isActive);
do_check_false(a9.foreignInstall);
do_check_true(a9.seen);
do_check_false(a9.hasBinaryComponents);
do_check_true(a9.strictCompatibility);
testserver.stop(do_test_finished);
});
}
function run_test() {
do_test_pending();
prepare_profile();
}

Просмотреть файл

@ -1,139 +0,0 @@
/* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/publicdomain/zero/1.0/
*/
// Checks that we fail to migrate but still start up ok when there is a SQLITE database
// with no useful data in it.
const PREF_GENERAL_SKINS_SELECTEDSKIN = "general.skins.selectedSkin";
var addon1 = {
id: "addon1@tests.mozilla.org",
version: "1.0",
name: "Test 1",
targetApplications: [{
id: "xpcshell@tests.mozilla.org",
minVersion: "1",
maxVersion: "1"
}]
};
var addon2 = {
id: "addon2@tests.mozilla.org",
version: "2.0",
name: "Test 5",
targetApplications: [{
id: "xpcshell@tests.mozilla.org",
minVersion: "0",
maxVersion: "0"
}]
};
var defaultTheme = {
id: "default@tests.mozilla.org",
version: "2.0",
name: "Default theme",
internalName: "classic/1.0",
targetApplications: [{
id: "xpcshell@tests.mozilla.org",
minVersion: "1",
maxVersion: "1"
}]
};
var theme1 = {
id: "theme1@tests.mozilla.org",
version: "2.0",
name: "Test theme",
internalName: "theme1/1.0",
targetApplications: [{
id: "xpcshell@tests.mozilla.org",
minVersion: "1",
maxVersion: "1"
}]
};
const profileDir = gProfD.clone();
profileDir.append("extensions");
function run_test() {
do_test_pending();
createAppInfo("xpcshell@tests.mozilla.org", "XPCShell", "1", "1.9.2");
writeInstallRDFForExtension(addon1, profileDir);
writeInstallRDFForExtension(addon2, profileDir);
writeInstallRDFForExtension(defaultTheme, profileDir);
writeInstallRDFForExtension(theme1, profileDir);
Services.prefs.setCharPref(PREF_GENERAL_SKINS_SELECTEDSKIN, "theme1/1.0");
// Write out a broken database (no userDisabled field)
let dbfile = gProfD.clone();
dbfile.append("extensions.sqlite");
let db = AM_Cc["@mozilla.org/storage/service;1"].
getService(AM_Ci.mozIStorageService).
openDatabase(dbfile);
db.createTable("addon", "internal_id INTEGER PRIMARY KEY AUTOINCREMENT, " +
"id TEXT, location TEXT, version TEXT, active INTEGER, " +
"installDate INTEGER");
db.createTable("targetApplication", "addon_internal_id INTEGER, " +
"id TEXT, minVersion TEXT, maxVersion TEXT");
let stmt = db.createStatement("INSERT INTO addon VALUES (NULL, :id, :location, " +
":version, :active, :installDate)");
let internal_ids = {};
[["addon1@tests.mozilla.org", "app-profile", "1.0", "1", "0"],
["addon2@tests.mozilla.org", "app-profile", "2.0", "0", "0"],
["default@tests.mozilla.org", "app-profile", "2.0", "1", "0"],
["theme1@tests.mozilla.org", "app-profile", "2.0", "0", "0"]].forEach(function(a) {
stmt.params.id = a[0];
stmt.params.location = a[1];
stmt.params.version = a[2];
stmt.params.active = a[3];
stmt.params.installDate = a[4];
stmt.execute();
internal_ids[a[0]] = db.lastInsertRowID;
});
stmt.finalize();
db.schemaVersion = 100;
Services.prefs.setIntPref("extensions.databaseSchema", 100);
db.close();
startupManager();
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",
"default@tests.mozilla.org",
"theme1@tests.mozilla.org"],
function([a1, a2, d, t1]) {
do_check_neq(a1, null);
do_check_false(a1.userDisabled);
do_check_false(a1.appDisabled);
do_check_true(a1.isActive);
do_check_neq(a2, null);
do_check_false(a2.userDisabled);
do_check_true(a2.appDisabled);
do_check_false(a2.isActive);
// Should have enabled the selected theme
do_check_neq(t1, null);
do_check_false(t1.userDisabled);
do_check_false(t1.appDisabled);
do_check_true(t1.isActive);
do_check_neq(d, null);
do_check_true(d.userDisabled);
do_check_false(d.appDisabled);
do_check_false(d.isActive);
do_execute_soon(do_test_finished);
});
}

Просмотреть файл

@ -1,127 +0,0 @@
/* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/publicdomain/zero/1.0/
*/
const EXPECTED_SCHEMA_VERSION = 4;
var dbfile;
function run_test() {
do_test_pending();
createAppInfo("xpcshell@tests.mozilla.org", "XPCShell", "1", "1.9.2");
// Write out a minimal database.
dbfile = gProfD.clone();
dbfile.append("addons.sqlite");
let db = AM_Cc["@mozilla.org/storage/service;1"].
getService(AM_Ci.mozIStorageService).
openDatabase(dbfile);
db.createTable("addon",
"internal_id INTEGER PRIMARY KEY AUTOINCREMENT, " +
"id TEXT UNIQUE, " +
"type TEXT, " +
"name TEXT, " +
"version TEXT, " +
"creator TEXT, " +
"creatorURL TEXT, " +
"description TEXT, " +
"fullDescription TEXT, " +
"developerComments TEXT, " +
"eula TEXT, " +
"iconURL TEXT, " +
"homepageURL TEXT, " +
"supportURL TEXT, " +
"contributionURL TEXT, " +
"contributionAmount TEXT, " +
"averageRating INTEGER, " +
"reviewCount INTEGER, " +
"reviewURL TEXT, " +
"totalDownloads INTEGER, " +
"weeklyDownloads INTEGER, " +
"dailyUsers INTEGER, " +
"sourceURI TEXT, " +
"repositoryStatus INTEGER, " +
"size INTEGER, " +
"updateDate INTEGER");
db.createTable("developer",
"addon_internal_id INTEGER, " +
"num INTEGER, " +
"name TEXT, " +
"url TEXT, " +
"PRIMARY KEY (addon_internal_id, num)");
db.createTable("screenshot",
"addon_internal_id INTEGER, " +
"num INTEGER, " +
"url TEXT, " +
"thumbnailURL TEXT, " +
"caption TEXT, " +
"PRIMARY KEY (addon_internal_id, num)");
let insertStmt = db.createStatement("INSERT INTO addon (id) VALUES (:id)");
insertStmt.params.id = "test1@tests.mozilla.org";
insertStmt.execute();
insertStmt.finalize();
insertStmt = db.createStatement("INSERT INTO screenshot VALUES " +
"(:addon_internal_id, :num, :url, :thumbnailURL, :caption)");
insertStmt.params.addon_internal_id = 1;
insertStmt.params.num = 0;
insertStmt.params.url = "http://localhost/full1-1.png";
insertStmt.params.thumbnailURL = "http://localhost/thumbnail1-1.png";
insertStmt.params.caption = "Caption 1 - 1";
insertStmt.execute();
insertStmt.finalize();
db.schemaVersion = 1;
db.close();
Services.prefs.setBoolPref("extensions.getAddons.cache.enabled", true);
AddonRepository.getCachedAddonByID("test1@tests.mozilla.org", function(aAddon) {
do_check_neq(aAddon, null);
do_check_eq(aAddon.screenshots.length, 1);
do_check_true(aAddon.screenshots[0].width === null);
do_check_true(aAddon.screenshots[0].height === null);
do_check_true(aAddon.screenshots[0].thumbnailWidth === null);
do_check_true(aAddon.screenshots[0].thumbnailHeight === null);
do_check_eq(aAddon.iconURL, undefined);
do_check_eq(JSON.stringify(aAddon.icons), "{}");
AddonRepository.shutdown().then(
function checkAfterRepoShutdown() {
// Check the DB schema has changed once AddonRepository has freed it.
db = AM_Cc["@mozilla.org/storage/service;1"].
getService(AM_Ci.mozIStorageService).
openDatabase(dbfile);
do_check_eq(db.schemaVersion, EXPECTED_SCHEMA_VERSION);
do_check_true(db.indexExists("developer_idx"));
do_check_true(db.indexExists("screenshot_idx"));
do_check_true(db.indexExists("compatibility_override_idx"));
do_check_true(db.tableExists("compatibility_override"));
do_check_true(db.indexExists("icon_idx"));
do_check_true(db.tableExists("icon"));
// Check the trigger is working
db.executeSimpleSQL("INSERT INTO addon (id, type, name) VALUES('test_addon', 'extension', 'Test Addon')");
let internalID = db.lastInsertRowID;
db.executeSimpleSQL("INSERT INTO compatibility_override (addon_internal_id, num, type) VALUES('" + internalID + "', '1', 'incompatible')");
let selectStmt = db.createStatement("SELECT COUNT(*) AS count FROM compatibility_override");
selectStmt.executeStep();
do_check_eq(selectStmt.row.count, 1);
selectStmt.reset();
db.executeSimpleSQL("DELETE FROM addon");
selectStmt.executeStep();
do_check_eq(selectStmt.row.count, 0);
selectStmt.finalize();
db.close();
do_test_finished();
},
do_report_unexpected_exception
);
});
}

Просмотреть файл

@ -1,103 +0,0 @@
/* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/publicdomain/zero/1.0/
*/
// Checks that we don't migrate data from SQLITE if
// the "extensions.databaseSchema" preference shows we've
// already upgraded to JSON
// Enable loading extensions from the user and system scopes
Services.prefs.setIntPref("extensions.enabledScopes",
AddonManager.SCOPE_PROFILE + AddonManager.SCOPE_USER +
AddonManager.SCOPE_SYSTEM);
var addon1 = {
id: "addon1@tests.mozilla.org",
version: "1.0",
name: "Test 1",
targetApplications: [{
id: "xpcshell@tests.mozilla.org",
minVersion: "1",
maxVersion: "1"
}]
};
createAppInfo("xpcshell@tests.mozilla.org", "XPCShell", "1", "1.9.2");
const profileDir = gProfD.clone();
profileDir.append("extensions");
function run_test() {
writeInstallRDFForExtension(addon1, profileDir);
// Write out a minimal database
let dbfile = gProfD.clone();
dbfile.append("extensions.sqlite");
let db = AM_Cc["@mozilla.org/storage/service;1"].
getService(AM_Ci.mozIStorageService).
openDatabase(dbfile);
db.createTable("addon", "internal_id INTEGER PRIMARY KEY AUTOINCREMENT, " +
"id TEXT, location TEXT, version TEXT, active INTEGER, " +
"userDisabled INTEGER, installDate INTEGER");
db.createTable("targetApplication", "addon_internal_id INTEGER, " +
"id TEXT, minVersion TEXT, maxVersion TEXT");
let stmt = db.createStatement("INSERT INTO addon VALUES (NULL, :id, :location, " +
":version, :active, :userDisabled, :installDate)");
let internal_ids = {};
let a = ["addon1@tests.mozilla.org", "app-profile", "1.0", "0", "1", "0"];
stmt.params.id = a[0];
stmt.params.location = a[1];
stmt.params.version = a[2];
stmt.params.active = a[3];
stmt.params.userDisabled = a[4];
stmt.params.installDate = a[5];
stmt.execute();
internal_ids[a[0]] = db.lastInsertRowID;
stmt.finalize();
db.schemaVersion = 14;
Services.prefs.setIntPref("extensions.databaseSchema", 14);
db.close();
startupManager();
run_next_test();
}
add_test(function before_rebuild() {
AddonManager.getAddonByID("addon1@tests.mozilla.org",
function check_before_rebuild(a1) {
// First check that it migrated OK once
// addon1 was disabled in the database
do_check_neq(a1, null);
do_check_true(a1.userDisabled);
do_check_false(a1.appDisabled);
do_check_false(a1.isActive);
do_check_false(a1.strictCompatibility);
do_check_false(a1.foreignInstall);
run_next_test();
});
});
// now shut down, remove the JSON database,
// start up again, and make sure the data didn't migrate this time
add_test(function rebuild_again() {
shutdownManager();
gExtensionsJSON.remove(true);
startupManager();
AddonManager.getAddonByID("addon1@tests.mozilla.org",
function check_after_rebuild(a1) {
// addon1 was rebuilt from extensions directory,
// so it appears enabled as a foreign install
do_check_neq(a1, null);
do_check_false(a1.userDisabled);
do_check_false(a1.appDisabled);
do_check_true(a1.isActive);
do_check_false(a1.strictCompatibility);
do_check_true(a1.foreignInstall);
run_next_test();
});
});

Просмотреть файл

@ -246,15 +246,6 @@ run-sequentially = Uses hardcoded ports in xpi files.
[test_mapURIToAddonID.js]
# Same as test_bootstrap.js
skip-if = os == "android"
[test_migrate1.js]
[test_migrate2.js]
[test_migrate3.js]
[test_migrate4.js]
# Times out during parallel runs on desktop
requesttimeoutfactor = 2
[test_migrate5.js]
[test_migrateAddonRepository.js]
[test_migrate_max_version.js]
[test_multiprocessCompatible.js]
[test_no_addons.js]
[test_onPropertyChanged_appDisabled.js]