Source code

Revision control

Copy as Markdown

Other Tools

Test Info: Warnings

/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*-
* vim: sw=4 ts=4 sts=4 et
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
// Display logging for ease of debugging.
let moz_log = "BackgroundTasks:5";
// Background task temporary profiles are created in the OS temporary directory.
// On Windows, we can put the temporary directory in a testing-specific location
// by setting TMP, per
// On Linux, this works as well: see
// On macOS, we can't set the temporary directory in this manner, so we will
// leak some temporary directories. It's important to test this functionality
// on macOS so we accept this.
let tmp = do_get_profile();
tmp.append("Temp");
add_setup(() => {
if (Services.env.exists("MOZ_LOG")) {
moz_log += `,${Services.env.get("MOZ_LOG")}`;
}
tmp.createUnique(Ci.nsIFile.DIRECTORY_TYPE, 0o700);
});
async function launch_one(index) {
let sentinel = Services.uuid.generateUUID().toString();
sentinel = sentinel.substring(1, sentinel.length - 1);
let stdoutLines = [];
let exitCode = await do_backgroundtask("unique_profile", {
extraArgs: [sentinel],
extraEnv: {
MOZ_BACKGROUNDTASKS_NO_REMOVE_PROFILE: "1",
MOZ_LOG: moz_log,
TMP: tmp.path, // Ignored on macOS.
},
onStdoutLine: line => stdoutLines.push(line),
});
let profile;
for (let line of stdoutLines) {
if (line.includes(sentinel)) {
let info = JSON.parse(line.split(sentinel)[1]);
profile = info[1];
}
}
return { index, sentinel, exitCode, profile };
}
add_task(async function test_backgroundtask_simultaneous_instances() {
let expectedCount = 10;
let promises = [];
for (let i = 0; i < expectedCount; i++) {
promises.push(launch_one(i));
}
let results = await Promise.all(promises);
registerCleanupFunction(() => {
for (let result of results) {
if (!result.profile) {
return;
}
let dir = Cc["@mozilla.org/file/local;1"].createInstance(Ci.nsIFile);
dir.initWithPath(result.profile);
try {
dir.remove();
} catch (e) {
console.warn("Could not clean up profile directory", e);
}
}
});
for (let result of results) {
Assert.equal(
0,
result.exitCode,
`Invocation ${result.index} with sentinel ${result.sentinel} exited with code 0`
);
Assert.ok(
result.profile,
`Invocation ${result.index} with sentinel ${result.sentinel} yielded a temporary profile directory`
);
}
let profiles = new Set(results.map(it => it.profile));
Assert.equal(
expectedCount,
profiles.size,
`Invocations used ${expectedCount} different temporary profile directories`
);
});