mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 602577: Recover from a corrupt database or incorrect schema after startup. r=robstrong, a=blocks-betaN
This commit is contained in:
parent
6e7b3e0366
commit
db0fcbb949
@ -1781,11 +1781,20 @@ var XPIProvider = {
|
|||||||
* @param aUpdateCompatibility
|
* @param aUpdateCompatibility
|
||||||
* true to update add-ons appDisabled property when the application
|
* true to update add-ons appDisabled property when the application
|
||||||
* version has changed
|
* version has changed
|
||||||
|
* @param aMigrateData
|
||||||
|
* an object generated from a previous version of the database
|
||||||
|
* holding information about what add-ons were previously userDisabled
|
||||||
|
* and updated compatibility information if present
|
||||||
|
* @param aActiveBundles
|
||||||
|
* When performing recovery after startup this will be an array of
|
||||||
|
* persistent descriptors of add-ons that are known to be active,
|
||||||
|
* otherwise it will be null
|
||||||
* @return true if a change requiring a restart was detected
|
* @return true if a change requiring a restart was detected
|
||||||
*/
|
*/
|
||||||
processFileChanges: function XPI_processFileChanges(aState, aManifests,
|
processFileChanges: function XPI_processFileChanges(aState, aManifests,
|
||||||
aUpdateCompatibility,
|
aUpdateCompatibility,
|
||||||
aMigrateData) {
|
aMigrateData,
|
||||||
|
aActiveBundles) {
|
||||||
let visibleAddons = {};
|
let visibleAddons = {};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -2032,8 +2041,11 @@ var XPIProvider = {
|
|||||||
function addMetadata(aInstallLocation, aId, aAddonState, aMigrateData) {
|
function addMetadata(aInstallLocation, aId, aAddonState, aMigrateData) {
|
||||||
LOG("New add-on " + aId + " installed in " + aInstallLocation.name);
|
LOG("New add-on " + aId + " installed in " + aInstallLocation.name);
|
||||||
|
|
||||||
// Check the updated manifests lists for a manifest for this add-on
|
let newAddon = null;
|
||||||
let newAddon = aManifests[aInstallLocation.name][aId];
|
// Check the updated manifests lists for the install location, If there
|
||||||
|
// is no manifest for the add-on ID then newAddon will be undefined
|
||||||
|
if (aInstallLocation.name in aManifests)
|
||||||
|
newAddon = aManifests[aInstallLocation.name][aId];
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// Otherwise load the manifest from the add-on
|
// Otherwise load the manifest from the add-on
|
||||||
@ -2084,6 +2096,24 @@ var XPIProvider = {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// If we have a list of what add-ons should be marked as active then use it
|
||||||
|
if (aActiveBundles) {
|
||||||
|
// For themes we know which is active by the current skin setting
|
||||||
|
if (newAddon.type == "theme")
|
||||||
|
newAddon.active = newAddon.internalName == XPIProvider.currentSkin;
|
||||||
|
else
|
||||||
|
newAddon.active = aActiveBundles.indexOf(aAddonState.descriptor) != -1;
|
||||||
|
|
||||||
|
// If the add-on isn't active and it isn't appDisabled then it is
|
||||||
|
// probably userDisabled
|
||||||
|
if (!newAddon.active && newAddon.visible && !newAddon.appDisabled)
|
||||||
|
newAddon.userDisabled = true;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
newAddon.active = (newAddon.visible && !newAddon.userDisabled &&
|
||||||
|
!newAddon.appDisabled)
|
||||||
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// Update the database.
|
// Update the database.
|
||||||
XPIDatabase.addAddonMetadata(newAddon, aAddonState.descriptor);
|
XPIDatabase.addAddonMetadata(newAddon, aAddonState.descriptor);
|
||||||
@ -2275,57 +2305,54 @@ var XPIProvider = {
|
|||||||
if (aAppChanged !== false)
|
if (aAppChanged !== false)
|
||||||
this.importPermissions();
|
this.importPermissions();
|
||||||
|
|
||||||
// First install any new add-ons into the locations, we'll detect these when
|
// If the application version has changed then the database information
|
||||||
// we read the install state
|
// needs to be updated
|
||||||
|
let updateDatabase = aAppChanged;
|
||||||
|
|
||||||
|
// First install any new add-ons into the locations, if there are any
|
||||||
|
// changes then we must update the database with the information in the
|
||||||
|
// install locations
|
||||||
let manifests = {};
|
let manifests = {};
|
||||||
let changed = this.processPendingFileChanges(manifests);
|
updateDatabase = this.processPendingFileChanges(manifests) | updateDatabase;
|
||||||
|
|
||||||
// We have to hold the DB scheme in prefs so we don't need to load the
|
// This will be true if the previous session made changes that affect the
|
||||||
// database to see if we need to migrate data
|
// active state of add-ons but didn't commit them properly (normally due
|
||||||
let schema = Prefs.getIntPref(PREF_DB_SCHEMA, 0);
|
// to the application crashing)
|
||||||
|
let hasPendingChanges = Prefs.getBoolPref(PREF_PENDING_OPERATIONS);
|
||||||
|
|
||||||
let migrateData = null;
|
// If the schema appears to have changed then we should update the database
|
||||||
let cache = null;
|
updateDatabase |= DB_SCHEMA != Prefs.getIntPref(PREF_DB_SCHEMA, 0);
|
||||||
if (schema != DB_SCHEMA) {
|
|
||||||
// The schema has changed so migrate data from the old schema
|
// Load the list of bootstrapped add-ons first so processFileChanges can
|
||||||
migrateData = XPIDatabase.migrateData(schema);
|
// modify it
|
||||||
}
|
this.bootstrappedAddons = JSON.parse(Prefs.getCharPref(PREF_BOOTSTRAP_ADDONS,
|
||||||
|
"{}"));
|
||||||
|
|
||||||
|
let state = this.getInstallLocationStates();
|
||||||
|
|
||||||
// If the database exists then the previous file cache can be trusted
|
// If the database exists then the previous file cache can be trusted
|
||||||
// otherwise create an empty database
|
// otherwise the database needs to be recreated
|
||||||
let db = FileUtils.getFile(KEY_PROFILEDIR, [FILE_DATABASE], true);
|
let dbFile = FileUtils.getFile(KEY_PROFILEDIR, [FILE_DATABASE], true);
|
||||||
if (db.exists()) {
|
updateDatabase |= !dbFile.exists();
|
||||||
cache = Prefs.getCharPref(PREF_INSTALL_CACHE, null);
|
if (!updateDatabase) {
|
||||||
}
|
// If the state has changed then we must update the database
|
||||||
else {
|
let cache = Prefs.getCharPref(PREF_INSTALL_CACHE, null);
|
||||||
try {
|
updateDatabase |= cache != JSON.stringify(state);
|
||||||
LOG("Database is missing, recreating");
|
|
||||||
XPIDatabase.openConnection();
|
|
||||||
XPIDatabase.createSchema();
|
|
||||||
}
|
|
||||||
catch (e) {
|
|
||||||
try {
|
|
||||||
db.remove(true);
|
|
||||||
}
|
|
||||||
catch (e) {
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Catch any errors during the main startup and rollback the database changes
|
// Catch any errors during the main startup and rollback the database changes
|
||||||
XPIDatabase.beginTransaction();
|
XPIDatabase.beginTransaction();
|
||||||
try {
|
try {
|
||||||
// Load the list of bootstrapped add-ons first so processFileChanges can
|
let extensionListChanged = false;
|
||||||
// modify it
|
// If the database needs to be updated then open it and then update it
|
||||||
this.bootstrappedAddons = JSON.parse(Prefs.getCharPref(PREF_BOOTSTRAP_ADDONS,
|
// from the filesystem
|
||||||
"{}"));
|
if (updateDatabase || hasPendingChanges) {
|
||||||
let state = this.getInstallLocationStates();
|
let migrateData = XPIDatabase.openConnection(false);
|
||||||
if (aAppChanged || changed || cache == null ||
|
|
||||||
cache != JSON.stringify(state)) {
|
|
||||||
try {
|
try {
|
||||||
changed = this.processFileChanges(state, manifests, aAppChanged,
|
extensionListChanged = this.processFileChanges(state, manifests,
|
||||||
migrateData);
|
aAppChanged,
|
||||||
|
migrateData, null);
|
||||||
}
|
}
|
||||||
catch (e) {
|
catch (e) {
|
||||||
ERROR("Error processing file changes: " + e);
|
ERROR("Error processing file changes: " + e);
|
||||||
@ -2342,7 +2369,7 @@ var XPIProvider = {
|
|||||||
|
|
||||||
// If the application crashed before completing any pending operations then
|
// If the application crashed before completing any pending operations then
|
||||||
// we should perform them now.
|
// we should perform them now.
|
||||||
if (changed || Prefs.getBoolPref(PREF_PENDING_OPERATIONS)) {
|
if (extensionListChanged || hasPendingChanges) {
|
||||||
LOG("Updating database with changes to installed add-ons");
|
LOG("Updating database with changes to installed add-ons");
|
||||||
XPIDatabase.updateActiveAddons();
|
XPIDatabase.updateActiveAddons();
|
||||||
XPIDatabase.commitTransaction();
|
XPIDatabase.commitTransaction();
|
||||||
@ -3419,44 +3446,192 @@ var XPIDatabase = {
|
|||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Opens a new connection to the database file.
|
* Attempts to open the database file. If it fails it will try to delete the
|
||||||
|
* existing file and create an empty database. If that fails then it will
|
||||||
|
* open an in-memory database that can be used during this session.
|
||||||
*
|
*
|
||||||
|
* @param aDBFile
|
||||||
|
* The nsIFile to open
|
||||||
* @return the mozIStorageConnection for the database
|
* @return the mozIStorageConnection for the database
|
||||||
*/
|
*/
|
||||||
openConnection: function XPIDB_openConnection() {
|
openDatabaseFile: function XPIDB_openDatabaseFile(aDBFile) {
|
||||||
|
LOG("Opening database");
|
||||||
|
let connection = null;
|
||||||
|
|
||||||
|
// Attempt to open the database
|
||||||
|
try {
|
||||||
|
connection = Services.storage.openUnsharedDatabase(aDBFile);
|
||||||
|
}
|
||||||
|
catch (e) {
|
||||||
|
ERROR("Failed to open database (1st attempt): " + e);
|
||||||
|
try {
|
||||||
|
aDBFile.remove(true);
|
||||||
|
}
|
||||||
|
catch (e) {
|
||||||
|
ERROR("Failed to remove database that could not be opened: " + e);
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
connection = Services.storage.openUnsharedDatabase(aDBFile);
|
||||||
|
}
|
||||||
|
catch (e) {
|
||||||
|
ERROR("Failed to open database (2nd attempt): " + e);
|
||||||
|
|
||||||
|
// If we have got here there seems to be no way to open the real
|
||||||
|
// database, instead open a temporary memory database so things will
|
||||||
|
// work for this session
|
||||||
|
return Services.storage.openSpecialDatabase("memory");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
connection.executeSimpleSQL("PRAGMA synchronous = FULL");
|
||||||
|
connection.executeSimpleSQL("PRAGMA locking_mode = EXCLUSIVE");
|
||||||
|
|
||||||
|
return connection;
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Opens a new connection to the database file.
|
||||||
|
*
|
||||||
|
* @param aRebuildOnError
|
||||||
|
* A boolean indicating whether add-on information should be loaded
|
||||||
|
* from the install locations if the database needs to be rebuilt.
|
||||||
|
* @return the migration data from the database if it was an old schema or
|
||||||
|
* null otherwise.
|
||||||
|
*/
|
||||||
|
openConnection: function XPIDB_openConnection(aRebuildOnError) {
|
||||||
this.initialized = true;
|
this.initialized = true;
|
||||||
let dbfile = FileUtils.getFile(KEY_PROFILEDIR, [FILE_DATABASE], true);
|
let dbfile = FileUtils.getFile(KEY_PROFILEDIR, [FILE_DATABASE], true);
|
||||||
delete this.connection;
|
delete this.connection;
|
||||||
this.connection = Services.storage.openUnsharedDatabase(dbfile);
|
|
||||||
this.connection.executeSimpleSQL("PRAGMA synchronous = FULL");
|
this.connection = this.openDatabaseFile(dbfile);
|
||||||
this.connection.executeSimpleSQL("PRAGMA locking_mode = EXCLUSIVE");
|
|
||||||
|
let migrateData = null;
|
||||||
|
// If the database was corrupt or missing then the new blank database will
|
||||||
|
// have a schema version of 0.
|
||||||
|
let schemaVersion = this.connection.schemaVersion;
|
||||||
|
if (schemaVersion != DB_SCHEMA) {
|
||||||
|
// A non-zero schema version means that a schema has been successfully
|
||||||
|
// created in the database in the past so we might be able to get useful
|
||||||
|
// information from it
|
||||||
|
if (schemaVersion != 0) {
|
||||||
|
LOG("Migrating data from schema " + schemaVersion);
|
||||||
|
migrateData = this.getMigrateDataFromDatabase();
|
||||||
|
|
||||||
|
// Delete the existing database
|
||||||
|
this.connection.close();
|
||||||
|
try {
|
||||||
|
if (dbfile.exists())
|
||||||
|
dbfile.remove(true);
|
||||||
|
|
||||||
|
// Reopen an empty database
|
||||||
|
this.connection = this.openDatabaseFile(dbfile);
|
||||||
|
}
|
||||||
|
catch (e) {
|
||||||
|
ERROR("Failed to remove old database: " + e);
|
||||||
|
// If the file couldn't be deleted then fall back to an in-memory
|
||||||
|
// database
|
||||||
|
this.connection = Services.storage.openSpecialDatabase("memory");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (Prefs.getIntPref(PREF_DB_SCHEMA, 0) == 0) {
|
||||||
|
// Only migrate data from the RDF if we haven't done it before
|
||||||
|
LOG("Migrating data from extensions.rdf");
|
||||||
|
migrateData = this.getMigrateDataFromRDF();
|
||||||
|
}
|
||||||
|
|
||||||
|
// At this point the database should be completely empty
|
||||||
|
this.createSchema();
|
||||||
|
|
||||||
|
if (aRebuildOnError) {
|
||||||
|
let activeBundles = this.getActiveBundles();
|
||||||
|
WARN("Rebuilding add-ons database from installed extensions.");
|
||||||
|
this.beginTransaction();
|
||||||
|
try {
|
||||||
|
let state = XPIProvider.getInstallLocationStates();
|
||||||
|
XPIProvider.processFileChanges(state, {}, false, migrateData, activeBundles)
|
||||||
|
// Make sure to update the active add-ons and add-ons list on shutdown
|
||||||
|
Services.prefs.setBoolPref(PREF_PENDING_OPERATIONS, true);
|
||||||
|
this.commitTransaction();
|
||||||
|
}
|
||||||
|
catch (e) {
|
||||||
|
ERROR("Error processing file changes: " + e);
|
||||||
|
dump(e.stack);
|
||||||
|
this.rollbackTransaction();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// If the database connection has a file open then it has the right schema
|
||||||
|
// by now so make sure the preferences reflect that. If not then there is
|
||||||
|
// an in-memory database open which means a problem opening and deleting the
|
||||||
|
// real database, clear the schema preference to force trying to load the
|
||||||
|
// database on the next startup
|
||||||
|
if (this.connection.databaseFile) {
|
||||||
|
Services.prefs.setIntPref(PREF_DB_SCHEMA, DB_SCHEMA);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
try {
|
||||||
|
Services.prefs.clearUserPref(PREF_DB_SCHEMA);
|
||||||
|
}
|
||||||
|
catch (e) {
|
||||||
|
// The preference may not be defined
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Services.prefs.savePrefFile(null);
|
||||||
|
|
||||||
// Begin any pending transactions
|
// Begin any pending transactions
|
||||||
for (let i = 0; i < this.transactionCount; i++)
|
for (let i = 0; i < this.transactionCount; i++)
|
||||||
this.connection.executeSimpleSQL("SAVEPOINT 'default'");
|
this.connection.executeSimpleSQL("SAVEPOINT 'default'");
|
||||||
return this.connection;
|
return migrateData;
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A lazy getter for the database connection.
|
* A lazy getter for the database connection.
|
||||||
*/
|
*/
|
||||||
get connection() {
|
get connection() {
|
||||||
return this.openConnection();
|
this.openConnection(true);
|
||||||
|
return this.connection;
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Migrates data from a previous database schema.
|
* Gets the list of file descriptors of active extension directories or XPI
|
||||||
|
* files from the add-ons list. This must be loaded from disk since the
|
||||||
|
* directory service gives no easy way to get both directly. This list doesn't
|
||||||
|
* include themes as preferences already say which theme is currently active
|
||||||
*
|
*
|
||||||
* @param oldSchema
|
* @return an array of persisitent descriptors for the directories
|
||||||
* The previous schema
|
|
||||||
* @return an object holding information about what add-ons were previously
|
|
||||||
* userDisabled
|
|
||||||
*/
|
*/
|
||||||
migrateData: function XPIDB_migrateData(aOldSchema) {
|
getActiveBundles: function XPIDB_getActiveBundles() {
|
||||||
LOG("Migrating data from schema " + aOldSchema);
|
let bundles = [];
|
||||||
|
|
||||||
|
let addonsList = FileUtils.getFile(KEY_PROFILEDIR, [FILE_XPI_ADDONS_LIST],
|
||||||
|
true);
|
||||||
|
|
||||||
|
let iniFactory = Cc["@mozilla.org/xpcom/ini-parser-factory;1"].
|
||||||
|
getService(Ci.nsIINIParserFactory);
|
||||||
|
let parser = iniFactory.createINIParser(addonsList);
|
||||||
|
|
||||||
|
let keys = parser.getKeys("ExtensionDirs");
|
||||||
|
|
||||||
|
while (keys.hasMore())
|
||||||
|
bundles.push(parser.getString("ExtensionDirs", keys.getNext()));
|
||||||
|
|
||||||
|
// Also include the list of active bootstrapped extensions
|
||||||
|
for (let id in XPIProvider.bootstrappedAddons)
|
||||||
|
bundles.push(XPIProvider.bootstrappedAddons[id].descriptor);
|
||||||
|
|
||||||
|
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: function XPIDB_getMigrateDataFromRDF(aDbWasMissing) {
|
||||||
let migrateData = {};
|
let migrateData = {};
|
||||||
|
|
||||||
if (aOldSchema == 0) {
|
|
||||||
// Migrate data from extensions.rdf
|
// Migrate data from extensions.rdf
|
||||||
let rdffile = FileUtils.getFile(KEY_PROFILEDIR, [FILE_OLD_DATABASE], true);
|
let rdffile = FileUtils.getFile(KEY_PROFILEDIR, [FILE_OLD_DATABASE], true);
|
||||||
if (rdffile.exists()) {
|
if (rdffile.exists()) {
|
||||||
@ -3506,8 +3681,19 @@ var XPIDatabase = {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
else {
|
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: function XPIDB_getMigrateDataFromDatabase() {
|
||||||
|
let migrateData = {};
|
||||||
|
|
||||||
// Attempt to migrate data from a different (even future!) version of the
|
// Attempt to migrate data from a different (even future!) version of the
|
||||||
// database
|
// database
|
||||||
try {
|
try {
|
||||||
@ -3556,14 +3742,6 @@ var XPIDatabase = {
|
|||||||
if (stmt)
|
if (stmt)
|
||||||
stmt.finalize();
|
stmt.finalize();
|
||||||
}
|
}
|
||||||
this.connection.close();
|
|
||||||
this.initialized = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Delete any existing database file
|
|
||||||
let dbfile = FileUtils.getFile(KEY_PROFILEDIR, [FILE_DATABASE], true);
|
|
||||||
if (dbfile.exists())
|
|
||||||
dbfile.remove(true);
|
|
||||||
|
|
||||||
return migrateData;
|
return migrateData;
|
||||||
},
|
},
|
||||||
@ -3591,7 +3769,8 @@ var XPIDatabase = {
|
|||||||
// Re-create the connection smart getter to allow the database to be
|
// Re-create the connection smart getter to allow the database to be
|
||||||
// re-loaded during testing.
|
// re-loaded during testing.
|
||||||
this.__defineGetter__("connection", function() {
|
this.__defineGetter__("connection", function() {
|
||||||
return this.openConnection();
|
this.openConnection(true);
|
||||||
|
return this.connection;
|
||||||
});
|
});
|
||||||
|
|
||||||
connection.asyncClose(aCallback);
|
connection.asyncClose(aCallback);
|
||||||
@ -3687,7 +3866,6 @@ var XPIDatabase = {
|
|||||||
"DELETE FROM locale_strings WHERE locale_id=old.id; " +
|
"DELETE FROM locale_strings WHERE locale_id=old.id; " +
|
||||||
"END");
|
"END");
|
||||||
this.connection.schemaVersion = DB_SCHEMA;
|
this.connection.schemaVersion = DB_SCHEMA;
|
||||||
Services.prefs.setIntPref(PREF_DB_SCHEMA, DB_SCHEMA);
|
|
||||||
this.commitTransaction();
|
this.commitTransaction();
|
||||||
}
|
}
|
||||||
catch (e) {
|
catch (e) {
|
||||||
@ -4229,9 +4407,6 @@ var XPIDatabase = {
|
|||||||
return row;
|
return row;
|
||||||
}
|
}
|
||||||
|
|
||||||
aAddon.active = (aAddon.visible && !aAddon.userDisabled &&
|
|
||||||
!aAddon.appDisabled);
|
|
||||||
|
|
||||||
if (aAddon.visible) {
|
if (aAddon.visible) {
|
||||||
let stmt = this.getStatement("clearVisibleAddons");
|
let stmt = this.getStatement("clearVisibleAddons");
|
||||||
stmt.params.id = aAddon.id;
|
stmt.params.id = aAddon.id;
|
||||||
@ -4309,6 +4484,8 @@ var XPIDatabase = {
|
|||||||
this.removeAddonMetadata(aOldAddon);
|
this.removeAddonMetadata(aOldAddon);
|
||||||
aNewAddon.installDate = aOldAddon.installDate;
|
aNewAddon.installDate = aOldAddon.installDate;
|
||||||
aNewAddon.applyBackgroundUpdates = aOldAddon.applyBackgroundUpdates;
|
aNewAddon.applyBackgroundUpdates = aOldAddon.applyBackgroundUpdates;
|
||||||
|
aNewAddon.active = (aNewAddon.visible && !aNewAddon.userDisabled &&
|
||||||
|
!aNewAddon.appDisabled)
|
||||||
this.addAddonMetadata(aNewAddon, aDescriptor);
|
this.addAddonMetadata(aNewAddon, aDescriptor);
|
||||||
this.commitTransaction();
|
this.commitTransaction();
|
||||||
}
|
}
|
||||||
@ -5410,6 +5587,8 @@ AddonInstall.prototype = {
|
|||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
this.addon.installDate = this.addon.updateDate;
|
this.addon.installDate = this.addon.updateDate;
|
||||||
|
this.addon.active = (this.addon.visible && !this.addon.userDisabled &&
|
||||||
|
!this.addon.appDisabled)
|
||||||
XPIDatabase.addAddonMetadata(this.addon, file.persistentDescriptor);
|
XPIDatabase.addAddonMetadata(this.addon, file.persistentDescriptor);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -0,0 +1,44 @@
|
|||||||
|
<?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:addon3@tests.mozilla.org">
|
||||||
|
<em:updates>
|
||||||
|
<Seq>
|
||||||
|
<li>
|
||||||
|
<Description>
|
||||||
|
<em:version>1.0</em:version>
|
||||||
|
<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>
|
||||||
|
</li>
|
||||||
|
</Seq>
|
||||||
|
</em:updates>
|
||||||
|
</Description>
|
||||||
|
|
||||||
|
<Description about="urn:mozilla:extension:addon4@tests.mozilla.org">
|
||||||
|
<em:updates>
|
||||||
|
<Seq>
|
||||||
|
<li>
|
||||||
|
<Description>
|
||||||
|
<em:version>1.0</em:version>
|
||||||
|
<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>
|
||||||
|
</li>
|
||||||
|
</Seq>
|
||||||
|
</em:updates>
|
||||||
|
</Description>
|
||||||
|
|
||||||
|
</RDF>
|
@ -446,7 +446,7 @@ function createInstallRDF(aData) {
|
|||||||
|
|
||||||
["id", "version", "type", "internalName", "updateURL", "updateKey",
|
["id", "version", "type", "internalName", "updateURL", "updateKey",
|
||||||
"optionsURL", "aboutURL", "iconURL", "icon64URL",
|
"optionsURL", "aboutURL", "iconURL", "icon64URL",
|
||||||
"skinnable"].forEach(function(aProp) {
|
"skinnable", "bootstrap"].forEach(function(aProp) {
|
||||||
if (aProp in aData)
|
if (aProp in aData)
|
||||||
rdf += "<em:" + aProp + ">" + escapeXML(aData[aProp]) + "</em:" + aProp + ">\n";
|
rdf += "<em:" + aProp + ">" + escapeXML(aData[aProp]) + "</em:" + aProp + ">\n";
|
||||||
});
|
});
|
||||||
|
396
toolkit/mozapps/extensions/test/xpcshell/test_badschema.js
Normal file
396
toolkit/mozapps/extensions/test/xpcshell/test_badschema.js
Normal file
@ -0,0 +1,396 @@
|
|||||||
|
/* Any copyright is dedicated to the Public Domain.
|
||||||
|
* http://creativecommons.org/publicdomain/zero/1.0/
|
||||||
|
*/
|
||||||
|
|
||||||
|
// Checks that we rebuild something sensible from a database with a bad schema
|
||||||
|
|
||||||
|
|
||||||
|
do_load_httpd_js();
|
||||||
|
var testserver;
|
||||||
|
|
||||||
|
// The test extension uses an insecure update url.
|
||||||
|
Services.prefs.setBoolPref("extensions.checkUpdateSecurity", false);
|
||||||
|
|
||||||
|
// Will be enabled
|
||||||
|
var addon1 = {
|
||||||
|
id: "addon1@tests.mozilla.org",
|
||||||
|
version: "1.0",
|
||||||
|
name: "Test 1",
|
||||||
|
targetApplications: [{
|
||||||
|
id: "xpcshell@tests.mozilla.org",
|
||||||
|
minVersion: "2",
|
||||||
|
maxVersion: "2"
|
||||||
|
}]
|
||||||
|
};
|
||||||
|
|
||||||
|
// Will be disabled
|
||||||
|
var addon2 = {
|
||||||
|
id: "addon2@tests.mozilla.org",
|
||||||
|
version: "1.0",
|
||||||
|
name: "Test 2",
|
||||||
|
targetApplications: [{
|
||||||
|
id: "xpcshell@tests.mozilla.org",
|
||||||
|
minVersion: "2",
|
||||||
|
maxVersion: "2"
|
||||||
|
}]
|
||||||
|
};
|
||||||
|
|
||||||
|
// Will get a compatibility update and be enabled
|
||||||
|
var addon3 = {
|
||||||
|
id: "addon3@tests.mozilla.org",
|
||||||
|
version: "1.0",
|
||||||
|
name: "Test 3",
|
||||||
|
updateURL: "http://localhost:4444/data/test_corrupt.rdf",
|
||||||
|
targetApplications: [{
|
||||||
|
id: "xpcshell@tests.mozilla.org",
|
||||||
|
minVersion: "1",
|
||||||
|
maxVersion: "1"
|
||||||
|
}]
|
||||||
|
};
|
||||||
|
|
||||||
|
// Will get a compatibility update and be disabled
|
||||||
|
var addon4 = {
|
||||||
|
id: "addon4@tests.mozilla.org",
|
||||||
|
version: "1.0",
|
||||||
|
name: "Test 4",
|
||||||
|
updateURL: "http://localhost:4444/data/test_corrupt.rdf",
|
||||||
|
targetApplications: [{
|
||||||
|
id: "xpcshell@tests.mozilla.org",
|
||||||
|
minVersion: "1",
|
||||||
|
maxVersion: "1"
|
||||||
|
}]
|
||||||
|
};
|
||||||
|
|
||||||
|
// Stays incompatible
|
||||||
|
var addon5 = {
|
||||||
|
id: "addon5@tests.mozilla.org",
|
||||||
|
version: "1.0",
|
||||||
|
name: "Test 5",
|
||||||
|
targetApplications: [{
|
||||||
|
id: "xpcshell@tests.mozilla.org",
|
||||||
|
minVersion: "1",
|
||||||
|
maxVersion: "1"
|
||||||
|
}]
|
||||||
|
};
|
||||||
|
|
||||||
|
// Enabled bootstrapped
|
||||||
|
var addon6 = {
|
||||||
|
id: "addon6@tests.mozilla.org",
|
||||||
|
version: "1.0",
|
||||||
|
name: "Test 6",
|
||||||
|
bootstrap: "true",
|
||||||
|
targetApplications: [{
|
||||||
|
id: "xpcshell@tests.mozilla.org",
|
||||||
|
minVersion: "2",
|
||||||
|
maxVersion: "2"
|
||||||
|
}]
|
||||||
|
};
|
||||||
|
|
||||||
|
// Disabled bootstrapped
|
||||||
|
var addon7 = {
|
||||||
|
id: "addon7@tests.mozilla.org",
|
||||||
|
version: "1.0",
|
||||||
|
name: "Test 7",
|
||||||
|
bootstrap: "true",
|
||||||
|
targetApplications: [{
|
||||||
|
id: "xpcshell@tests.mozilla.org",
|
||||||
|
minVersion: "2",
|
||||||
|
maxVersion: "2"
|
||||||
|
}]
|
||||||
|
};
|
||||||
|
|
||||||
|
// The default theme
|
||||||
|
var theme1 = {
|
||||||
|
id: "theme1@tests.mozilla.org",
|
||||||
|
version: "1.0",
|
||||||
|
name: "Theme 1",
|
||||||
|
internalName: "classic/1.0",
|
||||||
|
targetApplications: [{
|
||||||
|
id: "xpcshell@tests.mozilla.org",
|
||||||
|
minVersion: "2",
|
||||||
|
maxVersion: "2"
|
||||||
|
}]
|
||||||
|
};
|
||||||
|
|
||||||
|
// The selected theme
|
||||||
|
var theme2 = {
|
||||||
|
id: "theme2@tests.mozilla.org",
|
||||||
|
version: "1.0",
|
||||||
|
name: "Theme 2",
|
||||||
|
internalName: "test/1.0",
|
||||||
|
targetApplications: [{
|
||||||
|
id: "xpcshell@tests.mozilla.org",
|
||||||
|
minVersion: "2",
|
||||||
|
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(addon6, profileDir);
|
||||||
|
writeInstallRDFForExtension(addon7, profileDir);
|
||||||
|
writeInstallRDFForExtension(theme1, profileDir);
|
||||||
|
writeInstallRDFForExtension(theme2, profileDir);
|
||||||
|
|
||||||
|
// Create and configure the HTTP server.
|
||||||
|
testserver = new nsHttpServer();
|
||||||
|
testserver.registerDirectory("/addons/", do_get_file("addons"));
|
||||||
|
testserver.registerDirectory("/data/", do_get_file("data"));
|
||||||
|
testserver.start(4444);
|
||||||
|
|
||||||
|
// Startup the profile and setup the initial state
|
||||||
|
startupManager();
|
||||||
|
|
||||||
|
AddonManager.getAddonsByIDs(["addon2@tests.mozilla.org",
|
||||||
|
"addon3@tests.mozilla.org",
|
||||||
|
"addon4@tests.mozilla.org",
|
||||||
|
"addon7@tests.mozilla.org",
|
||||||
|
"theme2@tests.mozilla.org"], function([a2, a3, a4,
|
||||||
|
a7, t2]) {
|
||||||
|
// Set up the initial state
|
||||||
|
a2.userDisabled = true;
|
||||||
|
a4.userDisabled = true;
|
||||||
|
a7.userDisabled = true;
|
||||||
|
t2.userDisabled = false;
|
||||||
|
a3.findUpdates({
|
||||||
|
onUpdateFinished: function() {
|
||||||
|
a4.findUpdates({
|
||||||
|
onUpdateFinished: function() {
|
||||||
|
restartManager();
|
||||||
|
|
||||||
|
run_test_1();
|
||||||
|
}
|
||||||
|
}, AddonManager.UPDATE_WHEN_PERIODIC_UPDATE);
|
||||||
|
}
|
||||||
|
}, AddonManager.UPDATE_WHEN_PERIODIC_UPDATE);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function end_test() {
|
||||||
|
testserver.stop(do_test_finished);
|
||||||
|
}
|
||||||
|
|
||||||
|
function run_test_1() {
|
||||||
|
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]) {
|
||||||
|
do_check_neq(a1, null);
|
||||||
|
do_check_true(a1.isActive);
|
||||||
|
do_check_false(a1.userDisabled);
|
||||||
|
do_check_false(a1.appDisabled);
|
||||||
|
do_check_eq(a1.pendingOperations, AddonManager.PENDING_NONE);
|
||||||
|
|
||||||
|
do_check_neq(a2, null);
|
||||||
|
do_check_false(a2.isActive);
|
||||||
|
do_check_true(a2.userDisabled);
|
||||||
|
do_check_false(a2.appDisabled);
|
||||||
|
do_check_eq(a2.pendingOperations, AddonManager.PENDING_NONE);
|
||||||
|
|
||||||
|
do_check_neq(a3, null);
|
||||||
|
do_check_true(a3.isActive);
|
||||||
|
do_check_false(a3.userDisabled);
|
||||||
|
do_check_false(a3.appDisabled);
|
||||||
|
do_check_eq(a3.pendingOperations, AddonManager.PENDING_NONE);
|
||||||
|
|
||||||
|
do_check_neq(a4, null);
|
||||||
|
do_check_false(a4.isActive);
|
||||||
|
do_check_true(a4.userDisabled);
|
||||||
|
do_check_false(a4.appDisabled);
|
||||||
|
do_check_eq(a4.pendingOperations, AddonManager.PENDING_NONE);
|
||||||
|
|
||||||
|
do_check_neq(a5, null);
|
||||||
|
do_check_false(a5.isActive);
|
||||||
|
do_check_false(a5.userDisabled);
|
||||||
|
do_check_true(a5.appDisabled);
|
||||||
|
do_check_eq(a5.pendingOperations, AddonManager.PENDING_NONE);
|
||||||
|
|
||||||
|
do_check_neq(a6, null);
|
||||||
|
do_check_true(a6.isActive);
|
||||||
|
do_check_false(a6.userDisabled);
|
||||||
|
do_check_false(a6.appDisabled);
|
||||||
|
do_check_eq(a6.pendingOperations, AddonManager.PENDING_NONE);
|
||||||
|
|
||||||
|
do_check_neq(a7, null);
|
||||||
|
do_check_false(a7.isActive);
|
||||||
|
do_check_true(a7.userDisabled);
|
||||||
|
do_check_false(a7.appDisabled);
|
||||||
|
do_check_eq(a7.pendingOperations, AddonManager.PENDING_NONE);
|
||||||
|
|
||||||
|
do_check_neq(t1, null);
|
||||||
|
do_check_false(t1.isActive);
|
||||||
|
do_check_true(t1.userDisabled);
|
||||||
|
do_check_false(t1.appDisabled);
|
||||||
|
do_check_eq(t1.pendingOperations, AddonManager.PENDING_NONE);
|
||||||
|
|
||||||
|
do_check_neq(t2, null);
|
||||||
|
do_check_true(t2.isActive);
|
||||||
|
do_check_false(t2.userDisabled);
|
||||||
|
do_check_false(t2.appDisabled);
|
||||||
|
do_check_eq(t2.pendingOperations, AddonManager.PENDING_NONE);
|
||||||
|
|
||||||
|
// After restarting the database won't be open and so can be replaced with
|
||||||
|
// a bad file
|
||||||
|
restartManager();
|
||||||
|
var dbfile = gProfD.clone();
|
||||||
|
dbfile.append("extensions.sqlite");
|
||||||
|
var db = Services.storage.openDatabase(dbfile);
|
||||||
|
db.schemaVersion = 100;
|
||||||
|
db.close();
|
||||||
|
|
||||||
|
// Accessing the add-ons should open and recover the database. Since
|
||||||
|
// migration occurs everything should be recovered correctly
|
||||||
|
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]) {
|
||||||
|
do_check_neq(a1, null);
|
||||||
|
do_check_true(a1.isActive);
|
||||||
|
do_check_false(a1.userDisabled);
|
||||||
|
do_check_false(a1.appDisabled);
|
||||||
|
do_check_eq(a1.pendingOperations, AddonManager.PENDING_NONE);
|
||||||
|
|
||||||
|
do_check_neq(a2, null);
|
||||||
|
do_check_false(a2.isActive);
|
||||||
|
do_check_true(a2.userDisabled);
|
||||||
|
do_check_false(a2.appDisabled);
|
||||||
|
do_check_eq(a2.pendingOperations, AddonManager.PENDING_NONE);
|
||||||
|
|
||||||
|
do_check_neq(a3, null);
|
||||||
|
do_check_true(a3.isActive);
|
||||||
|
do_check_false(a3.userDisabled);
|
||||||
|
do_check_false(a3.appDisabled);
|
||||||
|
do_check_eq(a3.pendingOperations, AddonManager.PENDING_NONE);
|
||||||
|
|
||||||
|
do_check_neq(a4, null);
|
||||||
|
do_check_false(a4.isActive);
|
||||||
|
do_check_true(a4.userDisabled);
|
||||||
|
do_check_false(a4.appDisabled);
|
||||||
|
do_check_eq(a4.pendingOperations, AddonManager.PENDING_NONE);
|
||||||
|
|
||||||
|
do_check_neq(a5, null);
|
||||||
|
do_check_false(a5.isActive);
|
||||||
|
do_check_false(a5.userDisabled);
|
||||||
|
do_check_true(a5.appDisabled);
|
||||||
|
do_check_eq(a5.pendingOperations, AddonManager.PENDING_NONE);
|
||||||
|
|
||||||
|
do_check_neq(a6, null);
|
||||||
|
do_check_true(a6.isActive);
|
||||||
|
do_check_false(a6.userDisabled);
|
||||||
|
do_check_false(a6.appDisabled);
|
||||||
|
do_check_eq(a6.pendingOperations, AddonManager.PENDING_NONE);
|
||||||
|
|
||||||
|
do_check_neq(a7, null);
|
||||||
|
do_check_false(a7.isActive);
|
||||||
|
do_check_true(a7.userDisabled);
|
||||||
|
do_check_false(a7.appDisabled);
|
||||||
|
do_check_eq(a7.pendingOperations, AddonManager.PENDING_NONE);
|
||||||
|
|
||||||
|
do_check_neq(t1, null);
|
||||||
|
do_check_false(t1.isActive);
|
||||||
|
do_check_true(t1.userDisabled);
|
||||||
|
do_check_false(t1.appDisabled);
|
||||||
|
do_check_eq(t1.pendingOperations, AddonManager.PENDING_NONE);
|
||||||
|
|
||||||
|
do_check_neq(t2, null);
|
||||||
|
do_check_true(t2.isActive);
|
||||||
|
do_check_false(t2.userDisabled);
|
||||||
|
do_check_false(t2.appDisabled);
|
||||||
|
do_check_eq(t2.pendingOperations, AddonManager.PENDING_NONE);
|
||||||
|
|
||||||
|
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",
|
||||||
|
"addon7@tests.mozilla.org",
|
||||||
|
"theme1@tests.mozilla.org",
|
||||||
|
"theme2@tests.mozilla.org"], function([a1, a2, a3,
|
||||||
|
a4, a5, a6,
|
||||||
|
a7, t1, t2]) {
|
||||||
|
do_check_neq(a1, null);
|
||||||
|
do_check_true(a1.isActive);
|
||||||
|
do_check_false(a1.userDisabled);
|
||||||
|
do_check_false(a1.appDisabled);
|
||||||
|
do_check_eq(a1.pendingOperations, AddonManager.PENDING_NONE);
|
||||||
|
|
||||||
|
do_check_neq(a2, null);
|
||||||
|
do_check_false(a2.isActive);
|
||||||
|
do_check_true(a2.userDisabled);
|
||||||
|
do_check_false(a2.appDisabled);
|
||||||
|
do_check_eq(a2.pendingOperations, AddonManager.PENDING_NONE);
|
||||||
|
|
||||||
|
do_check_neq(a3, null);
|
||||||
|
do_check_true(a3.isActive);
|
||||||
|
do_check_false(a3.userDisabled);
|
||||||
|
do_check_false(a3.appDisabled);
|
||||||
|
do_check_eq(a3.pendingOperations, AddonManager.PENDING_NONE);
|
||||||
|
|
||||||
|
do_check_neq(a4, null);
|
||||||
|
do_check_false(a4.isActive);
|
||||||
|
do_check_true(a4.userDisabled);
|
||||||
|
do_check_false(a4.appDisabled);
|
||||||
|
do_check_eq(a4.pendingOperations, AddonManager.PENDING_NONE);
|
||||||
|
|
||||||
|
do_check_neq(a5, null);
|
||||||
|
do_check_false(a5.isActive);
|
||||||
|
do_check_false(a5.userDisabled);
|
||||||
|
do_check_true(a5.appDisabled);
|
||||||
|
do_check_eq(a5.pendingOperations, AddonManager.PENDING_NONE);
|
||||||
|
|
||||||
|
do_check_neq(a6, null);
|
||||||
|
do_check_true(a6.isActive);
|
||||||
|
do_check_false(a6.userDisabled);
|
||||||
|
do_check_false(a6.appDisabled);
|
||||||
|
do_check_eq(a6.pendingOperations, AddonManager.PENDING_NONE);
|
||||||
|
|
||||||
|
do_check_neq(a7, null);
|
||||||
|
do_check_false(a7.isActive);
|
||||||
|
do_check_true(a7.userDisabled);
|
||||||
|
do_check_false(a7.appDisabled);
|
||||||
|
do_check_eq(a7.pendingOperations, AddonManager.PENDING_NONE);
|
||||||
|
|
||||||
|
do_check_neq(t1, null);
|
||||||
|
do_check_false(t1.isActive);
|
||||||
|
do_check_true(t1.userDisabled);
|
||||||
|
do_check_false(t1.appDisabled);
|
||||||
|
do_check_eq(t1.pendingOperations, AddonManager.PENDING_NONE);
|
||||||
|
|
||||||
|
do_check_neq(t2, null);
|
||||||
|
do_check_true(t2.isActive);
|
||||||
|
do_check_false(t2.userDisabled);
|
||||||
|
do_check_false(t2.appDisabled);
|
||||||
|
do_check_eq(t2.pendingOperations, AddonManager.PENDING_NONE);
|
||||||
|
|
||||||
|
end_test();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
400
toolkit/mozapps/extensions/test/xpcshell/test_corrupt.js
Normal file
400
toolkit/mozapps/extensions/test/xpcshell/test_corrupt.js
Normal file
@ -0,0 +1,400 @@
|
|||||||
|
/* Any copyright is dedicated to the Public Domain.
|
||||||
|
* http://creativecommons.org/publicdomain/zero/1.0/
|
||||||
|
*/
|
||||||
|
|
||||||
|
// Checks that we rebuild something sensible from a corrupt database
|
||||||
|
|
||||||
|
|
||||||
|
do_load_httpd_js();
|
||||||
|
var testserver;
|
||||||
|
|
||||||
|
// The test extension uses an insecure update url.
|
||||||
|
Services.prefs.setBoolPref("extensions.checkUpdateSecurity", false);
|
||||||
|
|
||||||
|
// Will be enabled
|
||||||
|
var addon1 = {
|
||||||
|
id: "addon1@tests.mozilla.org",
|
||||||
|
version: "1.0",
|
||||||
|
name: "Test 1",
|
||||||
|
targetApplications: [{
|
||||||
|
id: "xpcshell@tests.mozilla.org",
|
||||||
|
minVersion: "2",
|
||||||
|
maxVersion: "2"
|
||||||
|
}]
|
||||||
|
};
|
||||||
|
|
||||||
|
// Will be disabled
|
||||||
|
var addon2 = {
|
||||||
|
id: "addon2@tests.mozilla.org",
|
||||||
|
version: "1.0",
|
||||||
|
name: "Test 2",
|
||||||
|
targetApplications: [{
|
||||||
|
id: "xpcshell@tests.mozilla.org",
|
||||||
|
minVersion: "2",
|
||||||
|
maxVersion: "2"
|
||||||
|
}]
|
||||||
|
};
|
||||||
|
|
||||||
|
// Will get a compatibility update and be enabled
|
||||||
|
var addon3 = {
|
||||||
|
id: "addon3@tests.mozilla.org",
|
||||||
|
version: "1.0",
|
||||||
|
name: "Test 3",
|
||||||
|
updateURL: "http://localhost:4444/data/test_corrupt.rdf",
|
||||||
|
targetApplications: [{
|
||||||
|
id: "xpcshell@tests.mozilla.org",
|
||||||
|
minVersion: "1",
|
||||||
|
maxVersion: "1"
|
||||||
|
}]
|
||||||
|
};
|
||||||
|
|
||||||
|
// Will get a compatibility update and be disabled
|
||||||
|
var addon4 = {
|
||||||
|
id: "addon4@tests.mozilla.org",
|
||||||
|
version: "1.0",
|
||||||
|
name: "Test 4",
|
||||||
|
updateURL: "http://localhost:4444/data/test_corrupt.rdf",
|
||||||
|
targetApplications: [{
|
||||||
|
id: "xpcshell@tests.mozilla.org",
|
||||||
|
minVersion: "1",
|
||||||
|
maxVersion: "1"
|
||||||
|
}]
|
||||||
|
};
|
||||||
|
|
||||||
|
// Stays incompatible
|
||||||
|
var addon5 = {
|
||||||
|
id: "addon5@tests.mozilla.org",
|
||||||
|
version: "1.0",
|
||||||
|
name: "Test 5",
|
||||||
|
targetApplications: [{
|
||||||
|
id: "xpcshell@tests.mozilla.org",
|
||||||
|
minVersion: "1",
|
||||||
|
maxVersion: "1"
|
||||||
|
}]
|
||||||
|
};
|
||||||
|
|
||||||
|
// Enabled bootstrapped
|
||||||
|
var addon6 = {
|
||||||
|
id: "addon6@tests.mozilla.org",
|
||||||
|
version: "1.0",
|
||||||
|
name: "Test 6",
|
||||||
|
bootstrap: "true",
|
||||||
|
targetApplications: [{
|
||||||
|
id: "xpcshell@tests.mozilla.org",
|
||||||
|
minVersion: "2",
|
||||||
|
maxVersion: "2"
|
||||||
|
}]
|
||||||
|
};
|
||||||
|
|
||||||
|
// Disabled bootstrapped
|
||||||
|
var addon7 = {
|
||||||
|
id: "addon7@tests.mozilla.org",
|
||||||
|
version: "1.0",
|
||||||
|
name: "Test 7",
|
||||||
|
bootstrap: "true",
|
||||||
|
targetApplications: [{
|
||||||
|
id: "xpcshell@tests.mozilla.org",
|
||||||
|
minVersion: "2",
|
||||||
|
maxVersion: "2"
|
||||||
|
}]
|
||||||
|
};
|
||||||
|
|
||||||
|
// The default theme
|
||||||
|
var theme1 = {
|
||||||
|
id: "theme1@tests.mozilla.org",
|
||||||
|
version: "1.0",
|
||||||
|
name: "Theme 1",
|
||||||
|
internalName: "classic/1.0",
|
||||||
|
targetApplications: [{
|
||||||
|
id: "xpcshell@tests.mozilla.org",
|
||||||
|
minVersion: "2",
|
||||||
|
maxVersion: "2"
|
||||||
|
}]
|
||||||
|
};
|
||||||
|
|
||||||
|
// The selected theme
|
||||||
|
var theme2 = {
|
||||||
|
id: "theme2@tests.mozilla.org",
|
||||||
|
version: "1.0",
|
||||||
|
name: "Theme 2",
|
||||||
|
internalName: "test/1.0",
|
||||||
|
targetApplications: [{
|
||||||
|
id: "xpcshell@tests.mozilla.org",
|
||||||
|
minVersion: "2",
|
||||||
|
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(addon6, profileDir);
|
||||||
|
writeInstallRDFForExtension(addon7, profileDir);
|
||||||
|
writeInstallRDFForExtension(theme1, profileDir);
|
||||||
|
writeInstallRDFForExtension(theme2, profileDir);
|
||||||
|
|
||||||
|
// Create and configure the HTTP server.
|
||||||
|
testserver = new nsHttpServer();
|
||||||
|
testserver.registerDirectory("/addons/", do_get_file("addons"));
|
||||||
|
testserver.registerDirectory("/data/", do_get_file("data"));
|
||||||
|
testserver.start(4444);
|
||||||
|
|
||||||
|
// Startup the profile and setup the initial state
|
||||||
|
startupManager();
|
||||||
|
|
||||||
|
AddonManager.getAddonsByIDs(["addon2@tests.mozilla.org",
|
||||||
|
"addon3@tests.mozilla.org",
|
||||||
|
"addon4@tests.mozilla.org",
|
||||||
|
"addon7@tests.mozilla.org",
|
||||||
|
"theme2@tests.mozilla.org"], function([a2, a3, a4,
|
||||||
|
a7, t2]) {
|
||||||
|
// Set up the initial state
|
||||||
|
a2.userDisabled = true;
|
||||||
|
a4.userDisabled = true;
|
||||||
|
a7.userDisabled = true;
|
||||||
|
t2.userDisabled = false;
|
||||||
|
a3.findUpdates({
|
||||||
|
onUpdateFinished: function() {
|
||||||
|
a4.findUpdates({
|
||||||
|
onUpdateFinished: function() {
|
||||||
|
restartManager();
|
||||||
|
|
||||||
|
run_test_1();
|
||||||
|
}
|
||||||
|
}, AddonManager.UPDATE_WHEN_PERIODIC_UPDATE);
|
||||||
|
}
|
||||||
|
}, AddonManager.UPDATE_WHEN_PERIODIC_UPDATE);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function end_test() {
|
||||||
|
testserver.stop(do_test_finished);
|
||||||
|
}
|
||||||
|
|
||||||
|
function run_test_1() {
|
||||||
|
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]) {
|
||||||
|
do_check_neq(a1, null);
|
||||||
|
do_check_true(a1.isActive);
|
||||||
|
do_check_false(a1.userDisabled);
|
||||||
|
do_check_false(a1.appDisabled);
|
||||||
|
do_check_eq(a1.pendingOperations, AddonManager.PENDING_NONE);
|
||||||
|
|
||||||
|
do_check_neq(a2, null);
|
||||||
|
do_check_false(a2.isActive);
|
||||||
|
do_check_true(a2.userDisabled);
|
||||||
|
do_check_false(a2.appDisabled);
|
||||||
|
do_check_eq(a2.pendingOperations, AddonManager.PENDING_NONE);
|
||||||
|
|
||||||
|
do_check_neq(a3, null);
|
||||||
|
do_check_true(a3.isActive);
|
||||||
|
do_check_false(a3.userDisabled);
|
||||||
|
do_check_false(a3.appDisabled);
|
||||||
|
do_check_eq(a3.pendingOperations, AddonManager.PENDING_NONE);
|
||||||
|
|
||||||
|
do_check_neq(a4, null);
|
||||||
|
do_check_false(a4.isActive);
|
||||||
|
do_check_true(a4.userDisabled);
|
||||||
|
do_check_false(a4.appDisabled);
|
||||||
|
do_check_eq(a4.pendingOperations, AddonManager.PENDING_NONE);
|
||||||
|
|
||||||
|
do_check_neq(a5, null);
|
||||||
|
do_check_false(a5.isActive);
|
||||||
|
do_check_false(a5.userDisabled);
|
||||||
|
do_check_true(a5.appDisabled);
|
||||||
|
do_check_eq(a5.pendingOperations, AddonManager.PENDING_NONE);
|
||||||
|
|
||||||
|
do_check_neq(a6, null);
|
||||||
|
do_check_true(a6.isActive);
|
||||||
|
do_check_false(a6.userDisabled);
|
||||||
|
do_check_false(a6.appDisabled);
|
||||||
|
do_check_eq(a6.pendingOperations, AddonManager.PENDING_NONE);
|
||||||
|
|
||||||
|
do_check_neq(a7, null);
|
||||||
|
do_check_false(a7.isActive);
|
||||||
|
do_check_true(a7.userDisabled);
|
||||||
|
do_check_false(a7.appDisabled);
|
||||||
|
do_check_eq(a7.pendingOperations, AddonManager.PENDING_NONE);
|
||||||
|
|
||||||
|
do_check_neq(t1, null);
|
||||||
|
do_check_false(t1.isActive);
|
||||||
|
do_check_true(t1.userDisabled);
|
||||||
|
do_check_false(t1.appDisabled);
|
||||||
|
do_check_eq(t1.pendingOperations, AddonManager.PENDING_NONE);
|
||||||
|
|
||||||
|
do_check_neq(t2, null);
|
||||||
|
do_check_true(t2.isActive);
|
||||||
|
do_check_false(t2.userDisabled);
|
||||||
|
do_check_false(t2.appDisabled);
|
||||||
|
do_check_eq(t2.pendingOperations, AddonManager.PENDING_NONE);
|
||||||
|
|
||||||
|
// After restarting the database won't be open and so can be replaced with
|
||||||
|
// a bad file
|
||||||
|
restartManager();
|
||||||
|
var dbfile = gProfD.clone();
|
||||||
|
dbfile.append("extensions.sqlite");
|
||||||
|
dbfile.remove(true);
|
||||||
|
dbfile.create(AM_Ci.nsIFile.DIRECTORY_TYPE, 0755);
|
||||||
|
|
||||||
|
// Accessing the add-ons should open and recover the database
|
||||||
|
AddonManager.getAddonsByIDs(["addon1@tests.mozilla.org",
|
||||||
|
"addon2@tests.mozilla.org",
|
||||||
|
"addon3@tests.mozilla.org",
|
||||||
|
"addon4@tests.mozilla.org",
|
||||||
|
"addon5@tests.mozilla.org",
|
||||||
|
"theme1@tests.mozilla.org",
|
||||||
|
"theme2@tests.mozilla.org"], function([a1, a2, a3,
|
||||||
|
a4, a5, t1,
|
||||||
|
t2]) {
|
||||||
|
// Should be correctly recovered
|
||||||
|
do_check_neq(a1, null);
|
||||||
|
do_check_true(a1.isActive);
|
||||||
|
do_check_false(a1.userDisabled);
|
||||||
|
do_check_false(a1.appDisabled);
|
||||||
|
do_check_eq(a1.pendingOperations, AddonManager.PENDING_NONE);
|
||||||
|
|
||||||
|
// Should be correctly recovered
|
||||||
|
do_check_neq(a2, null);
|
||||||
|
do_check_false(a2.isActive);
|
||||||
|
do_check_true(a2.userDisabled);
|
||||||
|
do_check_false(a2.appDisabled);
|
||||||
|
do_check_eq(a2.pendingOperations, AddonManager.PENDING_NONE);
|
||||||
|
|
||||||
|
// The compatibility update won't be recovered but it should still be
|
||||||
|
// active for this session
|
||||||
|
do_check_neq(a3, null);
|
||||||
|
do_check_true(a3.isActive);
|
||||||
|
do_check_false(a3.userDisabled);
|
||||||
|
do_check_true(a3.appDisabled);
|
||||||
|
do_check_eq(a3.pendingOperations, AddonManager.PENDING_DISABLE);
|
||||||
|
|
||||||
|
// The compatibility update won't be recovered and it will not have been
|
||||||
|
// able to tell that it was previously userDisabled
|
||||||
|
do_check_neq(a4, null);
|
||||||
|
do_check_false(a4.isActive);
|
||||||
|
do_check_false(a4.userDisabled);
|
||||||
|
do_check_true(a4.appDisabled);
|
||||||
|
do_check_eq(a4.pendingOperations, AddonManager.PENDING_NONE);
|
||||||
|
|
||||||
|
do_check_neq(a5, null);
|
||||||
|
do_check_false(a5.isActive);
|
||||||
|
do_check_false(a5.userDisabled);
|
||||||
|
do_check_true(a5.appDisabled);
|
||||||
|
do_check_eq(a5.pendingOperations, AddonManager.PENDING_NONE);
|
||||||
|
|
||||||
|
do_check_neq(a6, null);
|
||||||
|
do_check_true(a6.isActive);
|
||||||
|
do_check_false(a6.userDisabled);
|
||||||
|
do_check_false(a6.appDisabled);
|
||||||
|
do_check_eq(a6.pendingOperations, AddonManager.PENDING_NONE);
|
||||||
|
|
||||||
|
do_check_neq(a7, null);
|
||||||
|
do_check_false(a7.isActive);
|
||||||
|
do_check_true(a7.userDisabled);
|
||||||
|
do_check_false(a7.appDisabled);
|
||||||
|
do_check_eq(a7.pendingOperations, AddonManager.PENDING_NONE);
|
||||||
|
|
||||||
|
// Should be correctly recovered
|
||||||
|
do_check_neq(t1, null);
|
||||||
|
do_check_false(t1.isActive);
|
||||||
|
do_check_true(t1.userDisabled);
|
||||||
|
do_check_false(t1.appDisabled);
|
||||||
|
do_check_eq(t1.pendingOperations, AddonManager.PENDING_NONE);
|
||||||
|
|
||||||
|
// Should be correctly recovered
|
||||||
|
do_check_neq(t2, null);
|
||||||
|
do_check_true(t2.isActive);
|
||||||
|
do_check_false(t2.userDisabled);
|
||||||
|
do_check_false(t2.appDisabled);
|
||||||
|
do_check_eq(t2.pendingOperations, AddonManager.PENDING_NONE);
|
||||||
|
|
||||||
|
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",
|
||||||
|
"addon7@tests.mozilla.org",
|
||||||
|
"theme1@tests.mozilla.org",
|
||||||
|
"theme2@tests.mozilla.org"], function([a1, a2, a3,
|
||||||
|
a4, a5, a6,
|
||||||
|
a7, t1, t2]) {
|
||||||
|
do_check_neq(a1, null);
|
||||||
|
do_check_true(a1.isActive);
|
||||||
|
do_check_false(a1.userDisabled);
|
||||||
|
do_check_false(a1.appDisabled);
|
||||||
|
do_check_eq(a1.pendingOperations, AddonManager.PENDING_NONE);
|
||||||
|
|
||||||
|
do_check_neq(a2, null);
|
||||||
|
do_check_false(a2.isActive);
|
||||||
|
do_check_true(a2.userDisabled);
|
||||||
|
do_check_false(a2.appDisabled);
|
||||||
|
do_check_eq(a2.pendingOperations, AddonManager.PENDING_NONE);
|
||||||
|
|
||||||
|
do_check_neq(a3, null);
|
||||||
|
do_check_false(a3.isActive);
|
||||||
|
do_check_false(a3.userDisabled);
|
||||||
|
do_check_true(a3.appDisabled);
|
||||||
|
do_check_eq(a3.pendingOperations, AddonManager.PENDING_NONE);
|
||||||
|
|
||||||
|
do_check_neq(a4, null);
|
||||||
|
do_check_false(a4.isActive);
|
||||||
|
do_check_false(a4.userDisabled);
|
||||||
|
do_check_true(a4.appDisabled);
|
||||||
|
do_check_eq(a4.pendingOperations, AddonManager.PENDING_NONE);
|
||||||
|
|
||||||
|
do_check_neq(a5, null);
|
||||||
|
do_check_false(a5.isActive);
|
||||||
|
do_check_false(a5.userDisabled);
|
||||||
|
do_check_true(a5.appDisabled);
|
||||||
|
do_check_eq(a5.pendingOperations, AddonManager.PENDING_NONE);
|
||||||
|
|
||||||
|
do_check_neq(a6, null);
|
||||||
|
do_check_true(a6.isActive);
|
||||||
|
do_check_false(a6.userDisabled);
|
||||||
|
do_check_false(a6.appDisabled);
|
||||||
|
do_check_eq(a6.pendingOperations, AddonManager.PENDING_NONE);
|
||||||
|
|
||||||
|
do_check_neq(a7, null);
|
||||||
|
do_check_false(a7.isActive);
|
||||||
|
do_check_true(a7.userDisabled);
|
||||||
|
do_check_false(a7.appDisabled);
|
||||||
|
do_check_eq(a7.pendingOperations, AddonManager.PENDING_NONE);
|
||||||
|
|
||||||
|
do_check_neq(t1, null);
|
||||||
|
do_check_false(t1.isActive);
|
||||||
|
do_check_true(t1.userDisabled);
|
||||||
|
do_check_false(t1.appDisabled);
|
||||||
|
do_check_eq(t1.pendingOperations, AddonManager.PENDING_NONE);
|
||||||
|
|
||||||
|
do_check_neq(t2, null);
|
||||||
|
do_check_true(t2.isActive);
|
||||||
|
do_check_false(t2.userDisabled);
|
||||||
|
do_check_false(t2.appDisabled);
|
||||||
|
do_check_eq(t2.pendingOperations, AddonManager.PENDING_NONE);
|
||||||
|
|
||||||
|
end_test();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
406
toolkit/mozapps/extensions/test/xpcshell/test_locked.js
Normal file
406
toolkit/mozapps/extensions/test/xpcshell/test_locked.js
Normal file
@ -0,0 +1,406 @@
|
|||||||
|
/* Any copyright is dedicated to the Public Domain.
|
||||||
|
* http://creativecommons.org/publicdomain/zero/1.0/
|
||||||
|
*/
|
||||||
|
|
||||||
|
// Checks that we rebuild something sensible from a corrupt database
|
||||||
|
|
||||||
|
|
||||||
|
do_load_httpd_js();
|
||||||
|
var testserver;
|
||||||
|
|
||||||
|
// The test extension uses an insecure update url.
|
||||||
|
Services.prefs.setBoolPref("extensions.checkUpdateSecurity", false);
|
||||||
|
|
||||||
|
// Will be enabled
|
||||||
|
var addon1 = {
|
||||||
|
id: "addon1@tests.mozilla.org",
|
||||||
|
version: "1.0",
|
||||||
|
name: "Test 1",
|
||||||
|
targetApplications: [{
|
||||||
|
id: "xpcshell@tests.mozilla.org",
|
||||||
|
minVersion: "2",
|
||||||
|
maxVersion: "2"
|
||||||
|
}]
|
||||||
|
};
|
||||||
|
|
||||||
|
// Will be disabled
|
||||||
|
var addon2 = {
|
||||||
|
id: "addon2@tests.mozilla.org",
|
||||||
|
version: "1.0",
|
||||||
|
name: "Test 2",
|
||||||
|
targetApplications: [{
|
||||||
|
id: "xpcshell@tests.mozilla.org",
|
||||||
|
minVersion: "2",
|
||||||
|
maxVersion: "2"
|
||||||
|
}]
|
||||||
|
};
|
||||||
|
|
||||||
|
// Will get a compatibility update and be enabled
|
||||||
|
var addon3 = {
|
||||||
|
id: "addon3@tests.mozilla.org",
|
||||||
|
version: "1.0",
|
||||||
|
name: "Test 3",
|
||||||
|
updateURL: "http://localhost:4444/data/test_corrupt.rdf",
|
||||||
|
targetApplications: [{
|
||||||
|
id: "xpcshell@tests.mozilla.org",
|
||||||
|
minVersion: "1",
|
||||||
|
maxVersion: "1"
|
||||||
|
}]
|
||||||
|
};
|
||||||
|
|
||||||
|
// Will get a compatibility update and be disabled
|
||||||
|
var addon4 = {
|
||||||
|
id: "addon4@tests.mozilla.org",
|
||||||
|
version: "1.0",
|
||||||
|
name: "Test 4",
|
||||||
|
updateURL: "http://localhost:4444/data/test_corrupt.rdf",
|
||||||
|
targetApplications: [{
|
||||||
|
id: "xpcshell@tests.mozilla.org",
|
||||||
|
minVersion: "1",
|
||||||
|
maxVersion: "1"
|
||||||
|
}]
|
||||||
|
};
|
||||||
|
|
||||||
|
// Stays incompatible
|
||||||
|
var addon5 = {
|
||||||
|
id: "addon5@tests.mozilla.org",
|
||||||
|
version: "1.0",
|
||||||
|
name: "Test 5",
|
||||||
|
targetApplications: [{
|
||||||
|
id: "xpcshell@tests.mozilla.org",
|
||||||
|
minVersion: "1",
|
||||||
|
maxVersion: "1"
|
||||||
|
}]
|
||||||
|
};
|
||||||
|
|
||||||
|
// Enabled bootstrapped
|
||||||
|
var addon6 = {
|
||||||
|
id: "addon6@tests.mozilla.org",
|
||||||
|
version: "1.0",
|
||||||
|
name: "Test 6",
|
||||||
|
bootstrap: "true",
|
||||||
|
targetApplications: [{
|
||||||
|
id: "xpcshell@tests.mozilla.org",
|
||||||
|
minVersion: "2",
|
||||||
|
maxVersion: "2"
|
||||||
|
}]
|
||||||
|
};
|
||||||
|
|
||||||
|
// Disabled bootstrapped
|
||||||
|
var addon7 = {
|
||||||
|
id: "addon7@tests.mozilla.org",
|
||||||
|
version: "1.0",
|
||||||
|
name: "Test 7",
|
||||||
|
bootstrap: "true",
|
||||||
|
targetApplications: [{
|
||||||
|
id: "xpcshell@tests.mozilla.org",
|
||||||
|
minVersion: "2",
|
||||||
|
maxVersion: "2"
|
||||||
|
}]
|
||||||
|
};
|
||||||
|
|
||||||
|
// The default theme
|
||||||
|
var theme1 = {
|
||||||
|
id: "theme1@tests.mozilla.org",
|
||||||
|
version: "1.0",
|
||||||
|
name: "Theme 1",
|
||||||
|
internalName: "classic/1.0",
|
||||||
|
targetApplications: [{
|
||||||
|
id: "xpcshell@tests.mozilla.org",
|
||||||
|
minVersion: "2",
|
||||||
|
maxVersion: "2"
|
||||||
|
}]
|
||||||
|
};
|
||||||
|
|
||||||
|
// The selected theme
|
||||||
|
var theme2 = {
|
||||||
|
id: "theme2@tests.mozilla.org",
|
||||||
|
version: "1.0",
|
||||||
|
name: "Theme 2",
|
||||||
|
internalName: "test/1.0",
|
||||||
|
targetApplications: [{
|
||||||
|
id: "xpcshell@tests.mozilla.org",
|
||||||
|
minVersion: "2",
|
||||||
|
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(addon6, profileDir);
|
||||||
|
writeInstallRDFForExtension(addon7, profileDir);
|
||||||
|
writeInstallRDFForExtension(theme1, profileDir);
|
||||||
|
writeInstallRDFForExtension(theme2, profileDir);
|
||||||
|
|
||||||
|
// Create and configure the HTTP server.
|
||||||
|
testserver = new nsHttpServer();
|
||||||
|
testserver.registerDirectory("/addons/", do_get_file("addons"));
|
||||||
|
testserver.registerDirectory("/data/", do_get_file("data"));
|
||||||
|
testserver.start(4444);
|
||||||
|
|
||||||
|
// Startup the profile and setup the initial state
|
||||||
|
startupManager();
|
||||||
|
|
||||||
|
AddonManager.getAddonsByIDs(["addon2@tests.mozilla.org",
|
||||||
|
"addon3@tests.mozilla.org",
|
||||||
|
"addon4@tests.mozilla.org",
|
||||||
|
"addon7@tests.mozilla.org",
|
||||||
|
"theme2@tests.mozilla.org"], function([a2, a3, a4,
|
||||||
|
a7, t2]) {
|
||||||
|
// Set up the initial state
|
||||||
|
a2.userDisabled = true;
|
||||||
|
a4.userDisabled = true;
|
||||||
|
a7.userDisabled = true;
|
||||||
|
t2.userDisabled = false;
|
||||||
|
a3.findUpdates({
|
||||||
|
onUpdateFinished: function() {
|
||||||
|
a4.findUpdates({
|
||||||
|
onUpdateFinished: function() {
|
||||||
|
restartManager();
|
||||||
|
|
||||||
|
run_test_1();
|
||||||
|
}
|
||||||
|
}, AddonManager.UPDATE_WHEN_PERIODIC_UPDATE);
|
||||||
|
}
|
||||||
|
}, AddonManager.UPDATE_WHEN_PERIODIC_UPDATE);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function end_test() {
|
||||||
|
testserver.stop(do_test_finished);
|
||||||
|
}
|
||||||
|
|
||||||
|
function run_test_1() {
|
||||||
|
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]) {
|
||||||
|
do_check_neq(a1, null);
|
||||||
|
do_check_true(a1.isActive);
|
||||||
|
do_check_false(a1.userDisabled);
|
||||||
|
do_check_false(a1.appDisabled);
|
||||||
|
do_check_eq(a1.pendingOperations, AddonManager.PENDING_NONE);
|
||||||
|
|
||||||
|
do_check_neq(a2, null);
|
||||||
|
do_check_false(a2.isActive);
|
||||||
|
do_check_true(a2.userDisabled);
|
||||||
|
do_check_false(a2.appDisabled);
|
||||||
|
do_check_eq(a2.pendingOperations, AddonManager.PENDING_NONE);
|
||||||
|
|
||||||
|
do_check_neq(a3, null);
|
||||||
|
do_check_true(a3.isActive);
|
||||||
|
do_check_false(a3.userDisabled);
|
||||||
|
do_check_false(a3.appDisabled);
|
||||||
|
do_check_eq(a3.pendingOperations, AddonManager.PENDING_NONE);
|
||||||
|
|
||||||
|
do_check_neq(a4, null);
|
||||||
|
do_check_false(a4.isActive);
|
||||||
|
do_check_true(a4.userDisabled);
|
||||||
|
do_check_false(a4.appDisabled);
|
||||||
|
do_check_eq(a4.pendingOperations, AddonManager.PENDING_NONE);
|
||||||
|
|
||||||
|
do_check_neq(a5, null);
|
||||||
|
do_check_false(a5.isActive);
|
||||||
|
do_check_false(a5.userDisabled);
|
||||||
|
do_check_true(a5.appDisabled);
|
||||||
|
do_check_eq(a5.pendingOperations, AddonManager.PENDING_NONE);
|
||||||
|
|
||||||
|
do_check_neq(a6, null);
|
||||||
|
do_check_true(a6.isActive);
|
||||||
|
do_check_false(a6.userDisabled);
|
||||||
|
do_check_false(a6.appDisabled);
|
||||||
|
do_check_eq(a6.pendingOperations, AddonManager.PENDING_NONE);
|
||||||
|
|
||||||
|
do_check_neq(a7, null);
|
||||||
|
do_check_false(a7.isActive);
|
||||||
|
do_check_true(a7.userDisabled);
|
||||||
|
do_check_false(a7.appDisabled);
|
||||||
|
do_check_eq(a7.pendingOperations, AddonManager.PENDING_NONE);
|
||||||
|
|
||||||
|
do_check_neq(t1, null);
|
||||||
|
do_check_false(t1.isActive);
|
||||||
|
do_check_true(t1.userDisabled);
|
||||||
|
do_check_false(t1.appDisabled);
|
||||||
|
do_check_eq(t1.pendingOperations, AddonManager.PENDING_NONE);
|
||||||
|
|
||||||
|
do_check_neq(t2, null);
|
||||||
|
do_check_true(t2.isActive);
|
||||||
|
do_check_false(t2.userDisabled);
|
||||||
|
do_check_false(t2.appDisabled);
|
||||||
|
do_check_eq(t2.pendingOperations, AddonManager.PENDING_NONE);
|
||||||
|
|
||||||
|
// After restarting the database won't be open and so can be replaced with
|
||||||
|
// a bad file
|
||||||
|
restartManager();
|
||||||
|
var dbfile = gProfD.clone();
|
||||||
|
dbfile.append("extensions.sqlite");
|
||||||
|
// Mark the file unreadable
|
||||||
|
dbfile.permissions = 0000;
|
||||||
|
|
||||||
|
// Accessing the add-ons should open and recover the database
|
||||||
|
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]) {
|
||||||
|
// Should be correctly recovered
|
||||||
|
do_check_neq(a1, null);
|
||||||
|
do_check_true(a1.isActive);
|
||||||
|
do_check_false(a1.userDisabled);
|
||||||
|
do_check_false(a1.appDisabled);
|
||||||
|
do_check_eq(a1.pendingOperations, AddonManager.PENDING_NONE);
|
||||||
|
|
||||||
|
// Should be correctly recovered
|
||||||
|
do_check_neq(a2, null);
|
||||||
|
do_check_false(a2.isActive);
|
||||||
|
do_check_true(a2.userDisabled);
|
||||||
|
do_check_false(a2.appDisabled);
|
||||||
|
do_check_eq(a2.pendingOperations, AddonManager.PENDING_NONE);
|
||||||
|
|
||||||
|
// The compatibility update won't be recovered but it should still be
|
||||||
|
// active for this session
|
||||||
|
do_check_neq(a3, null);
|
||||||
|
do_check_true(a3.isActive);
|
||||||
|
do_check_false(a3.userDisabled);
|
||||||
|
do_check_true(a3.appDisabled);
|
||||||
|
do_check_eq(a3.pendingOperations, AddonManager.PENDING_DISABLE);
|
||||||
|
|
||||||
|
// The compatibility update won't be recovered and it will not have been
|
||||||
|
// able to tell that it was previously userDisabled
|
||||||
|
do_check_neq(a4, null);
|
||||||
|
do_check_false(a4.isActive);
|
||||||
|
do_check_false(a4.userDisabled);
|
||||||
|
do_check_true(a4.appDisabled);
|
||||||
|
do_check_eq(a4.pendingOperations, AddonManager.PENDING_NONE);
|
||||||
|
|
||||||
|
do_check_neq(a5, null);
|
||||||
|
do_check_false(a5.isActive);
|
||||||
|
do_check_false(a5.userDisabled);
|
||||||
|
do_check_true(a5.appDisabled);
|
||||||
|
do_check_eq(a5.pendingOperations, AddonManager.PENDING_NONE);
|
||||||
|
|
||||||
|
do_check_neq(a6, null);
|
||||||
|
do_check_true(a6.isActive);
|
||||||
|
do_check_false(a6.userDisabled);
|
||||||
|
do_check_false(a6.appDisabled);
|
||||||
|
do_check_eq(a6.pendingOperations, AddonManager.PENDING_NONE);
|
||||||
|
|
||||||
|
do_check_neq(a7, null);
|
||||||
|
do_check_false(a7.isActive);
|
||||||
|
do_check_true(a7.userDisabled);
|
||||||
|
do_check_false(a7.appDisabled);
|
||||||
|
do_check_eq(a7.pendingOperations, AddonManager.PENDING_NONE);
|
||||||
|
|
||||||
|
// Should be correctly recovered
|
||||||
|
do_check_neq(t1, null);
|
||||||
|
do_check_false(t1.isActive);
|
||||||
|
do_check_true(t1.userDisabled);
|
||||||
|
do_check_false(t1.appDisabled);
|
||||||
|
do_check_eq(t1.pendingOperations, AddonManager.PENDING_NONE);
|
||||||
|
|
||||||
|
// Should be correctly recovered
|
||||||
|
do_check_neq(t2, null);
|
||||||
|
do_check_true(t2.isActive);
|
||||||
|
do_check_false(t2.userDisabled);
|
||||||
|
do_check_false(t2.appDisabled);
|
||||||
|
do_check_eq(t2.pendingOperations, AddonManager.PENDING_NONE);
|
||||||
|
|
||||||
|
// Restarting will actually apply changes to extensions.ini which will
|
||||||
|
// then be put into the in-memory database when we next fail to load the
|
||||||
|
// real thing
|
||||||
|
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",
|
||||||
|
"addon7@tests.mozilla.org",
|
||||||
|
"theme1@tests.mozilla.org",
|
||||||
|
"theme2@tests.mozilla.org"], function([a1, a2, a3,
|
||||||
|
a4, a5, a6,
|
||||||
|
a7, t1, t2]) {
|
||||||
|
do_check_neq(a1, null);
|
||||||
|
do_check_true(a1.isActive);
|
||||||
|
do_check_false(a1.userDisabled);
|
||||||
|
do_check_false(a1.appDisabled);
|
||||||
|
do_check_eq(a1.pendingOperations, AddonManager.PENDING_NONE);
|
||||||
|
|
||||||
|
do_check_neq(a2, null);
|
||||||
|
do_check_false(a2.isActive);
|
||||||
|
do_check_true(a2.userDisabled);
|
||||||
|
do_check_false(a2.appDisabled);
|
||||||
|
do_check_eq(a2.pendingOperations, AddonManager.PENDING_NONE);
|
||||||
|
|
||||||
|
do_check_neq(a3, null);
|
||||||
|
do_check_false(a3.isActive);
|
||||||
|
do_check_false(a3.userDisabled);
|
||||||
|
do_check_true(a3.appDisabled);
|
||||||
|
do_check_eq(a3.pendingOperations, AddonManager.PENDING_NONE);
|
||||||
|
|
||||||
|
do_check_neq(a4, null);
|
||||||
|
do_check_false(a4.isActive);
|
||||||
|
do_check_false(a4.userDisabled);
|
||||||
|
do_check_true(a4.appDisabled);
|
||||||
|
do_check_eq(a4.pendingOperations, AddonManager.PENDING_NONE);
|
||||||
|
|
||||||
|
do_check_neq(a5, null);
|
||||||
|
do_check_false(a5.isActive);
|
||||||
|
do_check_false(a5.userDisabled);
|
||||||
|
do_check_true(a5.appDisabled);
|
||||||
|
do_check_eq(a5.pendingOperations, AddonManager.PENDING_NONE);
|
||||||
|
|
||||||
|
do_check_neq(a6, null);
|
||||||
|
do_check_true(a6.isActive);
|
||||||
|
do_check_false(a6.userDisabled);
|
||||||
|
do_check_false(a6.appDisabled);
|
||||||
|
do_check_eq(a6.pendingOperations, AddonManager.PENDING_NONE);
|
||||||
|
|
||||||
|
do_check_neq(a7, null);
|
||||||
|
do_check_false(a7.isActive);
|
||||||
|
do_check_true(a7.userDisabled);
|
||||||
|
do_check_false(a7.appDisabled);
|
||||||
|
do_check_eq(a7.pendingOperations, AddonManager.PENDING_NONE);
|
||||||
|
|
||||||
|
do_check_neq(t1, null);
|
||||||
|
do_check_false(t1.isActive);
|
||||||
|
do_check_true(t1.userDisabled);
|
||||||
|
do_check_false(t1.appDisabled);
|
||||||
|
do_check_eq(t1.pendingOperations, AddonManager.PENDING_NONE);
|
||||||
|
|
||||||
|
do_check_neq(t2, null);
|
||||||
|
do_check_true(t2.isActive);
|
||||||
|
do_check_false(t2.userDisabled);
|
||||||
|
do_check_false(t2.appDisabled);
|
||||||
|
do_check_eq(t2.pendingOperations, AddonManager.PENDING_NONE);
|
||||||
|
|
||||||
|
dbfile.permissions = 0644;
|
||||||
|
end_test();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
@ -134,8 +134,9 @@ function run_test() {
|
|||||||
stmt.execute();
|
stmt.execute();
|
||||||
stmt.finalize();
|
stmt.finalize();
|
||||||
|
|
||||||
db.close();
|
db.schemaVersion = 100;
|
||||||
Services.prefs.setIntPref("extensions.databaseSchema", 100);
|
Services.prefs.setIntPref("extensions.databaseSchema", 100);
|
||||||
|
db.close();
|
||||||
|
|
||||||
startupManager();
|
startupManager();
|
||||||
AddonManager.getAddonsByIDs(["addon1@tests.mozilla.org",
|
AddonManager.getAddonsByIDs(["addon1@tests.mozilla.org",
|
||||||
|
Loading…
Reference in New Issue
Block a user