summaryrefslogtreecommitdiffstats
path: root/toolkit/components/backgroundtasks/tests/xpcshell/test_backgroundtask_simultaneous_instances.js
diff options
context:
space:
mode:
Diffstat (limited to 'toolkit/components/backgroundtasks/tests/xpcshell/test_backgroundtask_simultaneous_instances.js')
-rw-r--r--toolkit/components/backgroundtasks/tests/xpcshell/test_backgroundtask_simultaneous_instances.js100
1 files changed, 100 insertions, 0 deletions
diff --git a/toolkit/components/backgroundtasks/tests/xpcshell/test_backgroundtask_simultaneous_instances.js b/toolkit/components/backgroundtasks/tests/xpcshell/test_backgroundtask_simultaneous_instances.js
new file mode 100644
index 0000000000..acae920849
--- /dev/null
+++ b/toolkit/components/backgroundtasks/tests/xpcshell/test_backgroundtask_simultaneous_instances.js
@@ -0,0 +1,100 @@
+/* -*- 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
+// https://docs.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-gettemppathw.
+// On Linux, this works as well: see
+// [GetSpecialSystemDirectory](https://searchfox.org/mozilla-central/source/xpcom/io/SpecialSystemDirectory.cpp).
+// 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`
+ );
+});