test_dbgsocket.js (4826B)
1 /* Any copyright is dedicated to the Public Domain. 2 http://creativecommons.org/publicdomain/zero/1.0/ */ 3 "use strict"; 4 5 /* global structuredClone */ 6 7 var gPort; 8 var gExtraListener; 9 10 function run_test() { 11 info("Starting test at " + new Date().toTimeString()); 12 initTestDevToolsServer(); 13 14 add_task(test_socket_conn); 15 add_task(test_socket_shutdown); 16 add_test(test_pipe_conn); 17 18 run_next_test(); 19 } 20 21 const { Actor } = require("resource://devtools/shared/protocol/Actor.js"); 22 class EchoTestActor extends Actor { 23 constructor(conn) { 24 super(conn, { typeName: "EchoTestActor", methods: [] }); 25 26 this.requestTypes = { 27 echo: EchoTestActor.prototype.onEcho, 28 }; 29 } 30 31 onEcho(request) { 32 /* 33 * Request packets are frozen. Copy request, so that 34 * DevToolsServerConnection.onPacket can attach a 'from' property. 35 */ 36 return structuredClone(request); 37 } 38 } 39 40 async function test_socket_conn() { 41 Assert.equal(DevToolsServer.listeningSockets, 0); 42 const AuthenticatorType = DevToolsServer.Authenticators.get("PROMPT"); 43 const authenticator = new AuthenticatorType.Server(); 44 authenticator.allowConnection = () => { 45 return DevToolsServer.AuthenticationResult.ALLOW; 46 }; 47 const socketOptions = { 48 authenticator, 49 portOrPath: -1, 50 }; 51 const listener = new SocketListener(DevToolsServer, socketOptions); 52 Assert.ok(listener); 53 listener.open(); 54 Assert.equal(DevToolsServer.listeningSockets, 1); 55 gPort = DevToolsServer._listeners[0].port; 56 info("DevTools server port is " + gPort); 57 // Open a second, separate listener 58 gExtraListener = new SocketListener(DevToolsServer, socketOptions); 59 gExtraListener.open(); 60 Assert.equal(DevToolsServer.listeningSockets, 2); 61 Assert.ok(!DevToolsServer.hasConnection()); 62 63 info("Starting long and unicode tests at " + new Date().toTimeString()); 64 // We can't use EventEmitter.once as this is the second argument we care about... 65 const onConnectionChange = new Promise(res => { 66 DevToolsServer.once("connectionchange", (type, conn) => res(conn)); 67 }); 68 69 const transport = await DevToolsClient.socketConnect({ 70 host: "127.0.0.1", 71 port: gPort, 72 }); 73 Assert.ok(DevToolsServer.hasConnection()); 74 info("Wait for server connection"); 75 const conn = await onConnectionChange; 76 77 // Register a custom actor to do echo requests 78 const actor = new EchoTestActor(conn); 79 actor.actorID = "echo-actor"; 80 conn.addActor(actor); 81 82 // Assert that connection settings are available on transport object 83 const settings = transport.connectionSettings; 84 Assert.equal(settings.host, "127.0.0.1"); 85 Assert.equal(settings.port, gPort); 86 87 const onDebuggerConnectionClosed = DevToolsServer.once("connectionchange"); 88 const unicodeString = "(╯°□°)╯︵ ┻━┻"; 89 await new Promise(resolve => { 90 transport.hooks = { 91 onPacket(packet) { 92 this.onPacket = function ({ unicode }) { 93 Assert.equal(unicode, unicodeString); 94 transport.close(); 95 }; 96 // Verify that things work correctly when bigger than the output 97 // transport buffers and when transporting unicode... 98 transport.send({ 99 to: "echo-actor", 100 type: "echo", 101 reallylong: really_long(), 102 unicode: unicodeString, 103 }); 104 Assert.equal(packet.from, "root"); 105 }, 106 onTransportClosed() { 107 resolve(); 108 }, 109 }; 110 transport.ready(); 111 }); 112 const type = await onDebuggerConnectionClosed; 113 Assert.equal(type, "closed"); 114 Assert.ok(!DevToolsServer.hasConnection()); 115 } 116 117 async function test_socket_shutdown() { 118 Assert.equal(DevToolsServer.listeningSockets, 2); 119 gExtraListener.close(); 120 Assert.equal(DevToolsServer.listeningSockets, 1); 121 Assert.ok(DevToolsServer.closeAllSocketListeners()); 122 Assert.equal(DevToolsServer.listeningSockets, 0); 123 // Make sure closing the listener twice does nothing. 124 Assert.ok(!DevToolsServer.closeAllSocketListeners()); 125 Assert.equal(DevToolsServer.listeningSockets, 0); 126 127 info("Connecting to a server socket at " + new Date().toTimeString()); 128 try { 129 await DevToolsClient.socketConnect({ 130 host: "127.0.0.1", 131 port: gPort, 132 }); 133 } catch (e) { 134 if ( 135 e.result == Cr.NS_ERROR_CONNECTION_REFUSED || 136 e.result == Cr.NS_ERROR_NET_TIMEOUT 137 ) { 138 // The connection should be refused here, but on slow or overloaded 139 // machines it may just time out. 140 Assert.ok(true); 141 return; 142 } 143 throw e; 144 } 145 146 // Shouldn't reach this, should never connect. 147 Assert.ok(false); 148 } 149 150 function test_pipe_conn() { 151 const transport = DevToolsServer.connectPipe(); 152 transport.hooks = { 153 onPacket(packet) { 154 Assert.equal(packet.from, "root"); 155 transport.close(); 156 }, 157 onTransportClosed() { 158 run_next_test(); 159 }, 160 }; 161 162 transport.ready(); 163 }