Bug 1435394 - Wait for the worker init to complete explicitly, before we continue with the test.
MozReview-Commit-ID: Aa16NVG0vNE
--- a/browser/components/sessionstore/SessionFile.jsm
+++ b/browser/components/sessionstore/SessionFile.jsm
@@ -189,16 +189,18 @@ var SessionFileInternal = {
// about the current status of the worker.
_workerHealth: {
failures: 0
},
// `true` once we have started initialization of the worker.
_initializationStarted: false,
+ _initWorkerPromise: null,
+
// A string that will be set to the session file name part that was read from
// disk. It will be available _after_ a session file read() is done.
_readOrigin: null,
// `true` if the old, uncompressed, file format was used to read from disk, as
// a fallback mechanism.
_usingOldExtension: false,
@@ -274,17 +276,17 @@ var SessionFileInternal = {
add(corrupted);
}
}
}
return {result, noFilesFound};
},
// Find the correct session file, read it and setup the worker.
- async read() {
+ async read(waitForInit = false) {
// Load session files with lz4 compression.
let {result, noFilesFound} = await this._readInternal(false);
if (!result) {
// No result? Probably because of migration, let's
// load uncompressed session files.
let r = await this._readInternal(true);
result = r.result;
}
@@ -305,16 +307,18 @@ var SessionFileInternal = {
}
this._readOrigin = result.origin;
result.noFilesFound = noFilesFound;
// Initialize the worker (in the background) to let it handle backups and also
// as a workaround for bug 964531.
this._initWorker();
+ if (waitForInit)
+ await this._initWorkerPromise;
return result;
},
// Initialize the worker in the background.
// Since this called _before_ any other messages are posted to the worker (see
// `_postToWorker()`), we know that this initialization process will be completed
// on time.
@@ -322,17 +326,17 @@ var SessionFileInternal = {
// In case of a worker crash/ shutdown during its initialization phase,
// `_checkWorkerHealth()` will detect it and flip the `_initializationStarted`
// property back to `false`. This means that we'll respawn the worker upon the
// next request, followed by the initialization sequence here. In other words;
// exactly the same procedure as when the worker crashed/ shut down 'regularly'.
//
// This will never throw an error.
_initWorker() {
- return new Promise(resolve => {
+ return this._initWorkerPromise = new Promise(resolve => {
if (this._initializationStarted) {
resolve();
return;
}
if (!this._readOrigin) {
throw new Error("_initWorker called too early! Please read the session file from disk first.");
}
--- a/browser/components/sessionstore/test/browser_upgrade_backup.js
+++ b/browser/components/sessionstore/test/browser_upgrade_backup.js
@@ -57,30 +57,30 @@ add_task(async function init() {
await SessionStore.promiseInitialized;
});
add_task(async function test_upgrade_backup() {
let test = prepareTest();
info("Let's check if we create an upgrade backup");
await SessionFile.wipe();
await OS.File.writeAtomic(Paths.clean, test.contents, {encoding: "utf-8", compression: "lz4"});
- await SessionFile.read(); // First call to read() initializes the SessionWorker
+ await SessionFile.read(true); // First call to read() initializes the SessionWorker
await SessionFile.write(""); // First call to write() triggers the backup
is(Services.prefs.getCharPref(PREF_UPGRADE), test.buildID, "upgrade backup should be set");
is((await OS.File.exists(Paths.upgradeBackup)), true, "upgrade backup file has been created");
let data = await OS.File.read(Paths.upgradeBackup, {compression: "lz4"});
is(test.contents, (new TextDecoder()).decode(data), "upgrade backup contains the expected contents");
info("Let's check that we don't overwrite this upgrade backup");
let newContents = JSON.stringify({"something else entirely": Math.random()});
await OS.File.writeAtomic(Paths.clean, newContents, {encoding: "utf-8", compression: "lz4"});
- await SessionFile.read(); // Reinitialize the SessionWorker
+ await SessionFile.read(true); // Reinitialize the SessionWorker
await SessionFile.write(""); // Next call to write() shouldn't trigger the backup
data = await OS.File.read(Paths.upgradeBackup, {compression: "lz4"});
is(test.contents, (new TextDecoder()).decode(data), "upgrade backup hasn't changed");
});
add_task(async function test_upgrade_backup_removal() {
let test = prepareTest();
let maxUpgradeBackups = Preferences.get(PREF_MAX_UPGRADE_BACKUPS, 3);
@@ -101,17 +101,17 @@ add_task(async function test_upgrade_bac
await OS.File.writeAtomic(Paths.upgradeBackupPrefix + "20110101010101", "", {encoding: "utf-8", compression: "lz4"});
await OS.File.writeAtomic(Paths.upgradeBackupPrefix + "20120101010101", "", {encoding: "utf-8", compression: "lz4"});
await OS.File.writeAtomic(Paths.upgradeBackupPrefix + "20130101010101", "", {encoding: "utf-8", compression: "lz4"});
// get currently existing backups
let backups = await getUpgradeBackups();
// trigger new backup
- await SessionFile.read(); // First call to read() initializes the SessionWorker
+ await SessionFile.read(true); // First call to read() initializes the SessionWorker
await SessionFile.write(""); // First call to write() triggers the backup and the cleanup
// a new backup should have been created (and still exist)
is(Services.prefs.getCharPref(PREF_UPGRADE), test.buildID, "upgrade backup should be set");
is((await OS.File.exists(Paths.upgradeBackup)), true, "upgrade backup file has been created");
// get currently existing backups and check their count
let newBackups = await getUpgradeBackups();