summaryrefslogtreecommitdiffstats
path: root/devtools/shared/security/tests/xpcshell
diff options
context:
space:
mode:
Diffstat (limited to 'devtools/shared/security/tests/xpcshell')
-rw-r--r--devtools/shared/security/tests/xpcshell/.eslintrc.js6
-rw-r--r--devtools/shared/security/tests/xpcshell/head_dbg.js95
-rw-r--r--devtools/shared/security/tests/xpcshell/test_devtools_socket_status.js137
-rw-r--r--devtools/shared/security/tests/xpcshell/testactors.js16
-rw-r--r--devtools/shared/security/tests/xpcshell/xpcshell.toml8
5 files changed, 262 insertions, 0 deletions
diff --git a/devtools/shared/security/tests/xpcshell/.eslintrc.js b/devtools/shared/security/tests/xpcshell/.eslintrc.js
new file mode 100644
index 0000000000..8611c174f5
--- /dev/null
+++ b/devtools/shared/security/tests/xpcshell/.eslintrc.js
@@ -0,0 +1,6 @@
+"use strict";
+
+module.exports = {
+ // Extend from the common devtools xpcshell eslintrc config.
+ extends: "../../../../.eslintrc.xpcshell.js",
+};
diff --git a/devtools/shared/security/tests/xpcshell/head_dbg.js b/devtools/shared/security/tests/xpcshell/head_dbg.js
new file mode 100644
index 0000000000..30359e6ac3
--- /dev/null
+++ b/devtools/shared/security/tests/xpcshell/head_dbg.js
@@ -0,0 +1,95 @@
+/* Any copyright is dedicated to the Public Domain.
+ http://creativecommons.org/publicdomain/zero/1.0/ */
+
+"use strict";
+
+/* exported DevToolsClient, initTestDevToolsServer */
+
+const { loader, require } = ChromeUtils.importESModule(
+ "resource://devtools/shared/loader/Loader.sys.mjs"
+);
+const xpcInspector = require("xpcInspector");
+const {
+ DevToolsServer,
+} = require("resource://devtools/server/devtools-server.js");
+const {
+ DevToolsClient,
+} = require("resource://devtools/client/devtools-client.js");
+// We need to require lazily since will be crashed if we load SocketListener too early
+// in xpc shell test due to SocketListener loads PSM module.
+loader.lazyRequireGetter(
+ this,
+ "SocketListener",
+ "resource://devtools/shared/security/socket.js",
+ true
+);
+
+// We do not want to log packets by default, because in some tests,
+// we can be sending large amounts of data. The test harness has
+// trouble dealing with logging all the data, and we end up with
+// intermittent time outs (e.g. bug 775924).
+// Services.prefs.setBoolPref("devtools.debugger.log", true);
+// Services.prefs.setBoolPref("devtools.debugger.log.verbose", true);
+// Enable remote debugging for the relevant tests.
+Services.prefs.setBoolPref("devtools.debugger.remote-enabled", true);
+
+// Convert an nsIScriptError 'logLevel' value into an appropriate string.
+function scriptErrorLogLevel(message) {
+ switch (message.logLevel) {
+ case Ci.nsIConsoleMessage.info:
+ return "info";
+ case Ci.nsIConsoleMessage.warn:
+ return "warning";
+ default:
+ Assert.equal(message.logLevel, Ci.nsIConsoleMessage.error);
+ return "error";
+ }
+}
+
+// Register a console listener, so console messages don't just disappear
+// into the ether.
+var listener = {
+ observe(message) {
+ let string;
+ try {
+ message.QueryInterface(Ci.nsIScriptError);
+ dump(
+ message.sourceName +
+ ":" +
+ message.lineNumber +
+ ": " +
+ scriptErrorLogLevel(message) +
+ ": " +
+ message.errorMessage +
+ "\n"
+ );
+ string = message.errorMessage;
+ } catch (ex) {
+ // Be a little paranoid with message, as the whole goal here is to lose
+ // no information.
+ try {
+ string = "" + message.message;
+ } catch (e) {
+ string = "<error converting error message to string>";
+ }
+ }
+
+ // Make sure we exit all nested event loops so that the test can finish.
+ while (xpcInspector.eventLoopNestLevel > 0) {
+ xpcInspector.exitNestedEventLoop();
+ }
+
+ info("head_dbg.js got console message: " + string + "\n");
+ },
+};
+
+Services.console.registerListener(listener);
+
+/**
+ * Initialize the testing devtools server.
+ */
+function initTestDevToolsServer() {
+ const { createRootActor } = require("xpcshell-test/testactors");
+ DevToolsServer.setRootActor(createRootActor);
+ DevToolsServer.init();
+}
diff --git a/devtools/shared/security/tests/xpcshell/test_devtools_socket_status.js b/devtools/shared/security/tests/xpcshell/test_devtools_socket_status.js
new file mode 100644
index 0000000000..2e41583b05
--- /dev/null
+++ b/devtools/shared/security/tests/xpcshell/test_devtools_socket_status.js
@@ -0,0 +1,137 @@
+/* Any copyright is dedicated to the Public Domain.
+ http://creativecommons.org/publicdomain/zero/1.0/ */
+
+"use strict";
+
+const {
+ useDistinctSystemPrincipalLoader,
+ releaseDistinctSystemPrincipalLoader,
+} = ChromeUtils.importESModule(
+ "resource://devtools/shared/loader/DistinctSystemPrincipalLoader.sys.mjs"
+);
+
+const { DevToolsSocketStatus } = ChromeUtils.importESModule(
+ "resource://devtools/shared/security/DevToolsSocketStatus.sys.mjs"
+);
+
+add_task(async function () {
+ Services.prefs.setBoolPref("devtools.debugger.remote-enabled", true);
+ Services.prefs.setBoolPref("devtools.debugger.prompt-connection", false);
+
+ info("Without any server started, all states should be set to false");
+ checkSocketStatus(false, false);
+
+ info("Start a first server, expect all states to change to true");
+ const server = await setupDevToolsServer({ fromBrowserToolbox: false });
+ checkSocketStatus(true, true);
+
+ info("Start another server, expect all states to remain true");
+ const otherServer = await setupDevToolsServer({ fromBrowserToolbox: false });
+ checkSocketStatus(true, true);
+
+ info("Shutdown one of the servers, expect all states to remain true");
+ teardownDevToolsServer(otherServer);
+ checkSocketStatus(true, true);
+
+ info("Shutdown the other server, expect all states to change to false");
+ teardownDevToolsServer(server);
+ checkSocketStatus(false, false);
+
+ info(
+ "Start a 'browser toolbox' server, expect only the 'include' state to become true"
+ );
+ const browserToolboxServer = await setupDevToolsServer({
+ fromBrowserToolbox: true,
+ });
+ checkSocketStatus(true, false);
+
+ info(
+ "Shutdown the 'browser toolbox' server, expect all states to become false"
+ );
+ teardownDevToolsServer(browserToolboxServer);
+ checkSocketStatus(false, false);
+
+ Services.prefs.clearUserPref("devtools.debugger.remote-enabled");
+ Services.prefs.clearUserPref("devtools.debugger.prompt-connection");
+});
+
+function checkSocketStatus(expectedExcludeFalse, expectedExcludeTrue) {
+ const openedDefault = DevToolsSocketStatus.hasSocketOpened();
+ const openedExcludeFalse = DevToolsSocketStatus.hasSocketOpened({
+ excludeBrowserToolboxSockets: false,
+ });
+ const openedExcludeTrue = DevToolsSocketStatus.hasSocketOpened({
+ excludeBrowserToolboxSockets: true,
+ });
+
+ equal(
+ openedDefault,
+ openedExcludeFalse,
+ "DevToolsSocketStatus.hasSocketOpened should default to excludeBrowserToolboxSockets=false"
+ );
+ equal(
+ openedExcludeFalse,
+ expectedExcludeFalse,
+ "DevToolsSocketStatus matches the expectation for excludeBrowserToolboxSockets=false"
+ );
+ equal(
+ openedExcludeTrue,
+ expectedExcludeTrue,
+ "DevToolsSocketStatus matches the expectation for excludeBrowserToolboxSockets=true"
+ );
+}
+
+async function setupDevToolsServer({ fromBrowserToolbox }) {
+ info("Use the dedicated system principal loader for the DevToolsServer.");
+ const requester = {};
+ const loader = useDistinctSystemPrincipalLoader(requester);
+
+ const { DevToolsServer } = loader.require(
+ "resource://devtools/server/devtools-server.js"
+ );
+
+ DevToolsServer.init();
+ DevToolsServer.registerAllActors();
+ DevToolsServer.allowChromeProcess = true;
+ const socketOptions = {
+ fromBrowserToolbox,
+ // Pass -1 to automatically choose an available port
+ portOrPath: -1,
+ };
+
+ const listener = new SocketListener(DevToolsServer, socketOptions);
+ ok(listener, "Socket listener created");
+
+ // Note that useDistinctSystemPrincipalLoader will lead to reuse the same
+ // loader if we are creating several servers in a row. The DevToolsServer
+ // singleton might already have sockets opened.
+ const listeningSockets = DevToolsServer.listeningSockets;
+ await listener.open();
+ equal(
+ DevToolsServer.listeningSockets,
+ listeningSockets + 1,
+ "A new listening socket was created"
+ );
+
+ return { DevToolsServer, listener, requester };
+}
+
+function teardownDevToolsServer({ DevToolsServer, listener, requester }) {
+ info("Close the listener socket");
+ const listeningSockets = DevToolsServer.listeningSockets;
+ listener.close();
+ equal(
+ DevToolsServer.listeningSockets,
+ listeningSockets - 1,
+ "A listening socket was closed"
+ );
+
+ if (DevToolsServer.listeningSockets == 0) {
+ info("Destroy the temporary devtools server");
+ DevToolsServer.destroy();
+ }
+
+ if (requester) {
+ releaseDistinctSystemPrincipalLoader(requester);
+ }
+}
diff --git a/devtools/shared/security/tests/xpcshell/testactors.js b/devtools/shared/security/tests/xpcshell/testactors.js
new file mode 100644
index 0000000000..0a35f05287
--- /dev/null
+++ b/devtools/shared/security/tests/xpcshell/testactors.js
@@ -0,0 +1,16 @@
+/* Any copyright is dedicated to the Public Domain.
+ http://creativecommons.org/publicdomain/zero/1.0/ */
+"use strict";
+
+const { RootActor } = require("resource://devtools/server/actors/root.js");
+const {
+ ActorRegistry,
+} = require("resource://devtools/server/actors/utils/actor-registry.js");
+
+exports.createRootActor = function createRootActor(connection) {
+ const root = new RootActor(connection, {
+ globalActorFactories: ActorRegistry.globalActorFactories,
+ });
+ root.applicationType = "xpcshell-tests";
+ return root;
+};
diff --git a/devtools/shared/security/tests/xpcshell/xpcshell.toml b/devtools/shared/security/tests/xpcshell/xpcshell.toml
new file mode 100644
index 0000000000..f0d3c8f1d2
--- /dev/null
+++ b/devtools/shared/security/tests/xpcshell/xpcshell.toml
@@ -0,0 +1,8 @@
+[DEFAULT]
+tags = "devtools"
+head = "head_dbg.js"
+skip-if = ["os == 'android'"]
+firefox-appdir = "browser"
+support-files = ["testactors.js"]
+
+["test_devtools_socket_status.js"]