summaryrefslogtreecommitdiffstats
path: root/toolkit/components/processtools/tests
diff options
context:
space:
mode:
Diffstat (limited to 'toolkit/components/processtools/tests')
-rw-r--r--toolkit/components/processtools/tests/browser/browser.ini9
-rw-r--r--toolkit/components/processtools/tests/browser/browser_test_procinfo.js173
-rw-r--r--toolkit/components/processtools/tests/browser/dummy.html20
-rw-r--r--toolkit/components/processtools/tests/xpcshell/test_process_kill.js57
-rw-r--r--toolkit/components/processtools/tests/xpcshell/xpcshell.ini6
5 files changed, 265 insertions, 0 deletions
diff --git a/toolkit/components/processtools/tests/browser/browser.ini b/toolkit/components/processtools/tests/browser/browser.ini
new file mode 100644
index 0000000000..77570e5b31
--- /dev/null
+++ b/toolkit/components/processtools/tests/browser/browser.ini
@@ -0,0 +1,9 @@
+[DEFAULT]
+prefs=
+ media.rdd-process.enabled=true
+
+support-files =
+ dummy.html
+
+[browser_test_procinfo.js]
+skip-if = (ccov && os == "linux") # https://bugzilla.mozilla.org/show_bug.cgi?id=1608080
diff --git a/toolkit/components/processtools/tests/browser/browser_test_procinfo.js b/toolkit/components/processtools/tests/browser/browser_test_procinfo.js
new file mode 100644
index 0000000000..87ceadf8fa
--- /dev/null
+++ b/toolkit/components/processtools/tests/browser/browser_test_procinfo.js
@@ -0,0 +1,173 @@
+/* -*- Mode: indent-tabs-mode: nil; js-indent-level: 2 -*- */
+/* vim: set sts=2 sw=2 et tw=80: */
+"use strict";
+
+const DUMMY_URL =
+ getRootDirectory(gTestPath).replace(
+ "chrome://mochitests/content",
+ "http://example.com"
+ ) + "/dummy.html";
+
+const { AppConstants } = ChromeUtils.import(
+ "resource://gre/modules/AppConstants.jsm"
+);
+const MAC = AppConstants.platform == "macosx";
+const HAS_THREAD_NAMES =
+ AppConstants.platform != "win" ||
+ AppConstants.isPlatformAndVersionAtLeast("win", 10);
+const isFissionEnabled = SpecialPowers.useRemoteSubframes;
+
+const SAMPLE_SIZE = 10;
+
+add_task(async function test_proc_info() {
+ console.log("YORIC", "Test starts");
+ // Open a few `about:home` tabs, they'll end up in `privilegedabout`.
+ let tabsAboutHome = [];
+ for (let i = 0; i < 5; ++i) {
+ let tab = BrowserTestUtils.addTab(gBrowser, "about:home");
+ tabsAboutHome.push(tab);
+ gBrowser.selectedTab = tab;
+ await BrowserTestUtils.browserLoaded(tab.linkedBrowser);
+ }
+
+ await BrowserTestUtils.withNewTab(
+ { gBrowser, url: DUMMY_URL },
+ async function(browser) {
+ let cpuThreads = 0;
+ let cpuUser = 0;
+
+ // We test `SAMPLE_SIZE` times to increase a tad the chance of encountering race conditions.
+ for (let z = 0; z < SAMPLE_SIZE; z++) {
+ let parentProc = await ChromeUtils.requestProcInfo();
+ cpuUser += parentProc.cpuUser;
+
+ Assert.equal(
+ parentProc.type,
+ "browser",
+ "Parent proc type should be browser"
+ );
+
+ for (var x = 0; x < parentProc.threads.length; x++) {
+ cpuThreads += parentProc.threads[x].cpuUser;
+ }
+
+ // Under Windows, thread names appeared with Windows 10.
+ if (HAS_THREAD_NAMES) {
+ Assert.ok(
+ parentProc.threads.some(thread => thread.name),
+ "At least one of the threads of the parent process is named"
+ );
+ }
+
+ Assert.ok(
+ parentProc.residentUniqueSize > 0,
+ "Resident-unique-size was set"
+ );
+ Assert.ok(
+ parentProc.residentUniqueSize <= parentProc.residentSetSize,
+ `Resident-unique-size should be bounded by resident-set-size ${parentProc.residentUniqueSize} <= ${parentProc.residentSetSize}`
+ );
+
+ // While it's very unlikely that the parent will disappear while we're running
+ // tests, some children can easily vanish. So we go twice through the list of
+ // children. Once to test stuff that all process data respects the invariants
+ // that don't care whether we have a race condition and once to test that at
+ // least one well-known process that should not be able to vanish during
+ // the test respects all the invariants.
+ for (var i = 0; i < parentProc.children.length; i++) {
+ let childProc = parentProc.children[i];
+ Assert.notEqual(
+ childProc.type,
+ "browser",
+ "Child proc type should not be browser"
+ );
+
+ // We set the `childID` for child processes that have a `ContentParent`/`ContentChild`
+ // actor hierarchy.
+ if (childProc.type.startsWith("web")) {
+ Assert.notEqual(
+ childProc.childID,
+ 0,
+ "Child proc should have been set"
+ );
+ }
+ Assert.notEqual(
+ childProc.type,
+ "unknown",
+ "Child proc type should be known"
+ );
+ if (childProc.type == "webIsolated") {
+ Assert.notEqual(
+ childProc.origin || "",
+ "",
+ "Child process should have an origin"
+ );
+ }
+
+ for (var y = 0; y < childProc.threads.length; y++) {
+ cpuThreads += childProc.threads[y].cpuUser;
+ }
+ cpuUser += childProc.cpuUser;
+ }
+
+ // We only check other properties on the `privilegedabout` subprocess, which
+ // as of this writing is always active and available.
+ var hasPrivilegedAbout = false;
+ var numberOfAboutTabs = 0;
+ for (i = 0; i < parentProc.children.length; i++) {
+ let childProc = parentProc.children[i];
+ if (childProc.type != "privilegedabout") {
+ continue;
+ }
+ hasPrivilegedAbout = true;
+ Assert.ok(
+ childProc.residentUniqueSize > 0,
+ "Resident-unique-size was set"
+ );
+ Assert.ok(
+ childProc.residentUniqueSize <= childProc.residentSetSize,
+ `Resident-unique-size should be bounded by resident-set-size ${childProc.residentUniqueSize} <= ${childProc.residentSetSize}`
+ );
+
+ for (var win of childProc.windows) {
+ if (win.documentURI.spec != "about:home") {
+ // We're only interested in about:home for this test.
+ continue;
+ }
+ numberOfAboutTabs++;
+ Assert.ok(
+ win.outerWindowId > 0,
+ `ContentParentID should be > 0 ${win.outerWindowId}`
+ );
+ if (win.documentTitle) {
+ // Unfortunately, we sometimes reach this point before the document is fully loaded, so
+ // `win.documentTitle` may still be empty.
+ Assert.equal(win.documentTitle, "New Tab");
+ }
+ }
+ Assert.ok(
+ numberOfAboutTabs >= tabsAboutHome.length,
+ "We have found at least as many about:home tabs as we opened"
+ );
+
+ // Once we have verified the privileged about process, bailout.
+ break;
+ }
+
+ Assert.ok(
+ hasPrivilegedAbout,
+ "We have found the privileged about process"
+ );
+ }
+ // see https://bugzilla.mozilla.org/show_bug.cgi?id=1529023
+ if (!MAC) {
+ Assert.greater(cpuThreads, 0, "Got some cpu time in the threads");
+ }
+ Assert.greater(cpuUser, 0, "Got some cpu time");
+
+ for (let tab of tabsAboutHome) {
+ BrowserTestUtils.removeTab(tab);
+ }
+ }
+ );
+});
diff --git a/toolkit/components/processtools/tests/browser/dummy.html b/toolkit/components/processtools/tests/browser/dummy.html
new file mode 100644
index 0000000000..e69dad24d4
--- /dev/null
+++ b/toolkit/components/processtools/tests/browser/dummy.html
@@ -0,0 +1,20 @@
+<!doctype html>
+<html>
+<head>
+<title>Dummy test page</title>
+<meta http-equiv="Content-Type" content="text/html;charset=utf-8"></meta>
+</head>
+<body>
+<p>Dummy test page</p>
+<div id="holder" class="">Holder</div>
+<script>
+ let text = "";
+ for (let i = 0; i < 1000; i++) {
+ text += "more";
+ // eslint-disable-next-line no-unsanitized/property
+ document.getElementById("holder").innerHTML = text;
+ }
+ document.getElementById("holder").classList.add("loaded");
+</script>
+</body>
+</html>
diff --git a/toolkit/components/processtools/tests/xpcshell/test_process_kill.js b/toolkit/components/processtools/tests/xpcshell/test_process_kill.js
new file mode 100644
index 0000000000..e8dce6d364
--- /dev/null
+++ b/toolkit/components/processtools/tests/xpcshell/test_process_kill.js
@@ -0,0 +1,57 @@
+/* eslint-disable mozilla/no-arbitrary-setTimeout */
+"use strict";
+
+const { AppConstants } = ChromeUtils.import(
+ "resource://gre/modules/AppConstants.jsm"
+);
+const { setTimeout } = ChromeUtils.import("resource://gre/modules/Timer.jsm");
+
+const { Subprocess } = ChromeUtils.import(
+ "resource://gre/modules/Subprocess.jsm"
+);
+
+const ProcessTools = Cc["@mozilla.org/processtools-service;1"].getService(
+ Ci.nsIProcessToolsService
+);
+
+const env = Cc["@mozilla.org/process/environment;1"].getService(
+ Ci.nsIEnvironment
+);
+
+let PYTHON;
+
+// Find Python.
+add_task(async function setup() {
+ PYTHON = await Subprocess.pathSearch(env.get("PYTHON"));
+});
+
+// Ensure that killing a process... kills the process.
+add_task(async function test_subprocess_kill() {
+ // We launch Python, as it's a long-running process and it exists
+ // on all desktop platforms on which we run tests.
+ let proc = await Subprocess.call({
+ command: PYTHON,
+ arguments: [],
+ });
+
+ let isTerminated = false;
+
+ proc.wait().then(() => {
+ isTerminated = true;
+ });
+
+ await new Promise(resolve => setTimeout(resolve, 100));
+ Assert.ok(
+ !isTerminated,
+ "We haven't killed the process yet, it should still be running."
+ );
+
+ // Time to kill the process.
+ ProcessTools.kill(proc.pid);
+
+ await new Promise(resolve => setTimeout(resolve, 100));
+ Assert.ok(
+ isTerminated,
+ "We have killed the process already, it shouldn't be running anymore."
+ );
+});
diff --git a/toolkit/components/processtools/tests/xpcshell/xpcshell.ini b/toolkit/components/processtools/tests/xpcshell/xpcshell.ini
new file mode 100644
index 0000000000..972282c114
--- /dev/null
+++ b/toolkit/components/processtools/tests/xpcshell/xpcshell.ini
@@ -0,0 +1,6 @@
+[DEFAULT]
+firefox-appdir = browser
+skip-if = os == 'android'
+subprocess = true
+
+[test_process_kill.js]