1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/netwerk/test/unit/test_unix_domain.js Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,545 @@ 1.4 +// Exercise Unix domain sockets. 1.5 + 1.6 +const CC = Components.Constructor; 1.7 + 1.8 +const UnixServerSocket = CC("@mozilla.org/network/server-socket;1", 1.9 + "nsIServerSocket", 1.10 + "initWithFilename"); 1.11 + 1.12 +const ScriptableInputStream = CC("@mozilla.org/scriptableinputstream;1", 1.13 + "nsIScriptableInputStream", 1.14 + "init"); 1.15 + 1.16 +const IOService = Cc["@mozilla.org/network/io-service;1"] 1.17 + .getService(Ci.nsIIOService); 1.18 +const socketTransportService = Cc["@mozilla.org/network/socket-transport-service;1"] 1.19 + .getService(Ci.nsISocketTransportService); 1.20 + 1.21 +const threadManager = Cc["@mozilla.org/thread-manager;1"].getService(); 1.22 + 1.23 +const allPermissions = parseInt("777", 8); 1.24 + 1.25 +function run_test() 1.26 +{ 1.27 + // If we're on Windows, simply check for graceful failure. 1.28 + if ("@mozilla.org/windows-registry-key;1" in Cc) { 1.29 + test_not_supported(); 1.30 + return; 1.31 + } 1.32 + 1.33 + add_test(test_echo); 1.34 + add_test(test_name_too_long); 1.35 + add_test(test_no_directory); 1.36 + add_test(test_no_such_socket); 1.37 + add_test(test_address_in_use); 1.38 + add_test(test_file_in_way); 1.39 + add_test(test_create_permission); 1.40 + add_test(test_connect_permission); 1.41 + add_test(test_long_socket_name); 1.42 + add_test(test_keep_when_offline); 1.43 + 1.44 + run_next_test(); 1.45 +} 1.46 + 1.47 +// Check that creating a Unix domain socket fails gracefully on Windows. 1.48 +function test_not_supported() 1.49 +{ 1.50 + let socketName = do_get_tempdir(); 1.51 + socketName.append('socket'); 1.52 + do_print("creating socket: " + socketName.path); 1.53 + 1.54 + do_check_throws_nsIException(() => new UnixServerSocket(socketName, allPermissions, -1), 1.55 + "NS_ERROR_SOCKET_ADDRESS_NOT_SUPPORTED"); 1.56 + 1.57 + do_check_throws_nsIException(() => socketTransportService.createUnixDomainTransport(socketName), 1.58 + "NS_ERROR_SOCKET_ADDRESS_NOT_SUPPORTED"); 1.59 +} 1.60 + 1.61 +// Actually exchange data with Unix domain sockets. 1.62 +function test_echo() 1.63 +{ 1.64 + let log = ''; 1.65 + 1.66 + let socketName = do_get_tempdir(); 1.67 + socketName.append('socket'); 1.68 + 1.69 + // Create a server socket, listening for connections. 1.70 + do_print("creating socket: " + socketName.path); 1.71 + let server = new UnixServerSocket(socketName, allPermissions, -1); 1.72 + server.asyncListen({ 1.73 + onSocketAccepted: function(aServ, aTransport) { 1.74 + do_print("called test_echo's onSocketAccepted"); 1.75 + log += 'a'; 1.76 + 1.77 + do_check_eq(aServ, server); 1.78 + 1.79 + let connection = aTransport; 1.80 + 1.81 + // Check the server socket's self address. 1.82 + let connectionSelfAddr = connection.getScriptableSelfAddr(); 1.83 + do_check_eq(connectionSelfAddr.family, Ci.nsINetAddr.FAMILY_LOCAL); 1.84 + do_check_eq(connectionSelfAddr.address, socketName.path); 1.85 + 1.86 + // The client socket is anonymous, so the server transport should 1.87 + // have an empty peer address. 1.88 + do_check_eq(connection.host, ''); 1.89 + do_check_eq(connection.port, 0); 1.90 + let connectionPeerAddr = connection.getScriptablePeerAddr(); 1.91 + do_check_eq(connectionPeerAddr.family, Ci.nsINetAddr.FAMILY_LOCAL); 1.92 + do_check_eq(connectionPeerAddr.address, ''); 1.93 + 1.94 + let serverAsyncInput = connection.openInputStream(0, 0, 0).QueryInterface(Ci.nsIAsyncInputStream); 1.95 + let serverOutput = connection.openOutputStream(0, 0, 0); 1.96 + 1.97 + serverAsyncInput.asyncWait(function (aStream) { 1.98 + do_print("called test_echo's server's onInputStreamReady"); 1.99 + let serverScriptableInput = new ScriptableInputStream(aStream); 1.100 + 1.101 + // Receive data from the client, and send back a response. 1.102 + do_check_eq(serverScriptableInput.readBytes(17), "Mervyn Murgatroyd"); 1.103 + do_print("server has read message from client"); 1.104 + serverOutput.write("Ruthven Murgatroyd", 18); 1.105 + do_print("server has written to client"); 1.106 + }, 0, 0, threadManager.currentThread); 1.107 + }, 1.108 + 1.109 + onStopListening: function(aServ, aStatus) { 1.110 + do_print("called test_echo's onStopListening"); 1.111 + log += 's'; 1.112 + 1.113 + do_check_eq(aServ, server); 1.114 + do_check_eq(log, 'acs'); 1.115 + 1.116 + run_next_test(); 1.117 + } 1.118 + }); 1.119 + 1.120 + // Create a client socket, and connect to the server. 1.121 + let client = socketTransportService.createUnixDomainTransport(socketName); 1.122 + do_check_eq(client.host, socketName.path); 1.123 + do_check_eq(client.port, 0); 1.124 + 1.125 + let clientAsyncInput = client.openInputStream(0, 0, 0).QueryInterface(Ci.nsIAsyncInputStream); 1.126 + let clientInput = new ScriptableInputStream(clientAsyncInput); 1.127 + let clientOutput = client.openOutputStream(0, 0, 0); 1.128 + 1.129 + clientOutput.write("Mervyn Murgatroyd", 17); 1.130 + do_print("client has written to server"); 1.131 + 1.132 + clientAsyncInput.asyncWait(function (aStream) { 1.133 + do_print("called test_echo's client's onInputStreamReady"); 1.134 + log += 'c'; 1.135 + 1.136 + do_check_eq(aStream, clientAsyncInput); 1.137 + 1.138 + // Now that the connection has been established, we can check the 1.139 + // transport's self and peer addresses. 1.140 + let clientSelfAddr = client.getScriptableSelfAddr(); 1.141 + do_check_eq(clientSelfAddr.family, Ci.nsINetAddr.FAMILY_LOCAL); 1.142 + do_check_eq(clientSelfAddr.address, ''); 1.143 + 1.144 + do_check_eq(client.host, socketName.path); // re-check, but hey 1.145 + let clientPeerAddr = client.getScriptablePeerAddr(); 1.146 + do_check_eq(clientPeerAddr.family, Ci.nsINetAddr.FAMILY_LOCAL); 1.147 + do_check_eq(clientPeerAddr.address, socketName.path); 1.148 + 1.149 + do_check_eq(clientInput.readBytes(18), "Ruthven Murgatroyd"); 1.150 + do_print("client has read message from server"); 1.151 + 1.152 + server.close(); 1.153 + }, 0, 0, threadManager.currentThread); 1.154 +} 1.155 + 1.156 +// Create client and server sockets using a path that's too long. 1.157 +function test_name_too_long() 1.158 +{ 1.159 + let socketName = do_get_tempdir(); 1.160 + // The length limits on all the systems NSPR supports are a bit past 100. 1.161 + socketName.append(new Array(1000).join('x')); 1.162 + 1.163 + // The length must be checked before we ever make any system calls --- we 1.164 + // have to create the sockaddr first --- so it's unambiguous which error 1.165 + // we should get here. 1.166 + 1.167 + do_check_throws_nsIException(() => new UnixServerSocket(socketName, 0, -1), 1.168 + "NS_ERROR_FILE_NAME_TOO_LONG"); 1.169 + 1.170 + // Unlike most other client socket errors, this one gets reported 1.171 + // immediately, as we can't even initialize the sockaddr with the given 1.172 + // name. 1.173 + do_check_throws_nsIException(() => socketTransportService.createUnixDomainTransport(socketName), 1.174 + "NS_ERROR_FILE_NAME_TOO_LONG"); 1.175 + 1.176 + run_next_test(); 1.177 +} 1.178 + 1.179 +// Try creating a socket in a directory that doesn't exist. 1.180 +function test_no_directory() 1.181 +{ 1.182 + let socketName = do_get_tempdir(); 1.183 + socketName.append('directory-that-does-not-exist'); 1.184 + socketName.append('socket'); 1.185 + 1.186 + do_check_throws_nsIException(() => new UnixServerSocket(socketName, 0, -1), 1.187 + "NS_ERROR_FILE_NOT_FOUND"); 1.188 + 1.189 + run_next_test(); 1.190 +} 1.191 + 1.192 +// Try connecting to a server socket that isn't there. 1.193 +function test_no_such_socket() 1.194 +{ 1.195 + let socketName = do_get_tempdir(); 1.196 + socketName.append('nonexistent-socket'); 1.197 + 1.198 + let client = socketTransportService.createUnixDomainTransport(socketName); 1.199 + let clientAsyncInput = client.openInputStream(0, 0, 0).QueryInterface(Ci.nsIAsyncInputStream); 1.200 + clientAsyncInput.asyncWait(function (aStream) { 1.201 + do_print("called test_no_such_socket's onInputStreamReady"); 1.202 + 1.203 + do_check_eq(aStream, clientAsyncInput); 1.204 + 1.205 + // nsISocketTransport puts off actually creating sockets as long as 1.206 + // possible, so the error in connecting doesn't actually show up until 1.207 + // this point. 1.208 + do_check_throws_nsIException(() => clientAsyncInput.available(), 1.209 + "NS_ERROR_FILE_NOT_FOUND"); 1.210 + 1.211 + clientAsyncInput.close(); 1.212 + client.close(Cr.NS_OK); 1.213 + 1.214 + run_next_test(); 1.215 + }, 0, 0, threadManager.currentThread); 1.216 +} 1.217 + 1.218 +// Creating a socket with a name that another socket is already using is an 1.219 +// error. 1.220 +function test_address_in_use() 1.221 +{ 1.222 + let socketName = do_get_tempdir(); 1.223 + socketName.append('socket-in-use'); 1.224 + 1.225 + // Create one server socket. 1.226 + let server = new UnixServerSocket(socketName, allPermissions, -1); 1.227 + 1.228 + // Now try to create another with the same name. 1.229 + do_check_throws_nsIException(() => new UnixServerSocket(socketName, allPermissions, -1), 1.230 + "NS_ERROR_SOCKET_ADDRESS_IN_USE"); 1.231 + 1.232 + run_next_test(); 1.233 +} 1.234 + 1.235 +// Creating a socket with a name that is already a file is an error. 1.236 +function test_file_in_way() 1.237 +{ 1.238 + let socketName = do_get_tempdir(); 1.239 + socketName.append('file_in_way'); 1.240 + 1.241 + // Create a file with the given name. 1.242 + socketName.create(Ci.nsIFile.NORMAL_FILE_TYPE, allPermissions); 1.243 + 1.244 + // Try to create a socket with the same name. 1.245 + do_check_throws_nsIException(() => new UnixServerSocket(socketName, allPermissions, -1), 1.246 + "NS_ERROR_SOCKET_ADDRESS_IN_USE"); 1.247 + 1.248 + // Try to create a socket under a name that uses that as a parent directory. 1.249 + socketName.append('socket'); 1.250 + do_check_throws_nsIException(() => new UnixServerSocket(socketName, 0, -1), 1.251 + "NS_ERROR_FILE_NOT_DIRECTORY"); 1.252 + 1.253 + run_next_test(); 1.254 +} 1.255 + 1.256 +// It is not permitted to create a socket in a directory which we are not 1.257 +// permitted to execute, or create files in. 1.258 +function test_create_permission() 1.259 +{ 1.260 + let dirName = do_get_tempdir(); 1.261 + dirName.append('unfriendly'); 1.262 + 1.263 + let socketName = dirName.clone(); 1.264 + socketName.append('socket'); 1.265 + 1.266 + // The test harness has difficulty cleaning things up if we don't make 1.267 + // everything writable before we're done. 1.268 + try { 1.269 + // Create a directory which we are not permitted to search. 1.270 + dirName.create(Ci.nsIFile.DIRECTORY_TYPE, 0); 1.271 + 1.272 + // Try to create a socket in that directory. Because Linux returns EACCES 1.273 + // when a 'connect' fails because of a local firewall rule, 1.274 + // nsIServerSocket returns NS_ERROR_CONNECTION_REFUSED in this case. 1.275 + do_check_throws_nsIException(() => new UnixServerSocket(socketName, allPermissions, -1), 1.276 + "NS_ERROR_CONNECTION_REFUSED"); 1.277 + 1.278 + // Grant read and execute permission, but not write permission on the directory. 1.279 + dirName.permissions = parseInt("0555", 8); 1.280 + 1.281 + // This should also fail; we need write permission. 1.282 + do_check_throws_nsIException(() => new UnixServerSocket(socketName, allPermissions, -1), 1.283 + "NS_ERROR_CONNECTION_REFUSED"); 1.284 + 1.285 + } finally { 1.286 + // Make the directory writable, so the test harness can clean it up. 1.287 + dirName.permissions = allPermissions; 1.288 + } 1.289 + 1.290 + // This should succeed, since we now have all the permissions on the 1.291 + // directory we could want. 1.292 + do_check_instanceof(new UnixServerSocket(socketName, allPermissions, -1), 1.293 + Ci.nsIServerSocket); 1.294 + 1.295 + run_next_test(); 1.296 +} 1.297 + 1.298 +// To connect to a Unix domain socket, we need search permission on the 1.299 +// directories containing it, and some kind of permission or other on the 1.300 +// socket itself. 1.301 +function test_connect_permission() 1.302 +{ 1.303 + // This test involves a lot of callbacks, but they're written out so that 1.304 + // the actual control flow proceeds from top to bottom. 1.305 + let log = ''; 1.306 + 1.307 + // Create a directory which we are permitted to search - at first. 1.308 + let dirName = do_get_tempdir(); 1.309 + dirName.append('inhospitable'); 1.310 + dirName.create(Ci.nsIFile.DIRECTORY_TYPE, allPermissions); 1.311 + 1.312 + let socketName = dirName.clone(); 1.313 + socketName.append('socket'); 1.314 + 1.315 + // Create a server socket in that directory, listening for connections, 1.316 + // and accessible. 1.317 + let server = new UnixServerSocket(socketName, allPermissions, -1); 1.318 + server.asyncListen({ onSocketAccepted: socketAccepted, onStopListening: stopListening }); 1.319 + 1.320 + // Make the directory unsearchable. 1.321 + dirName.permissions = 0; 1.322 + 1.323 + let client3; 1.324 + 1.325 + let client1 = socketTransportService.createUnixDomainTransport(socketName); 1.326 + let client1AsyncInput = client1.openInputStream(0, 0, 0).QueryInterface(Ci.nsIAsyncInputStream); 1.327 + client1AsyncInput.asyncWait(function (aStream) { 1.328 + do_print("called test_connect_permission's client1's onInputStreamReady"); 1.329 + log += '1'; 1.330 + 1.331 + // nsISocketTransport puts off actually creating sockets as long as 1.332 + // possible, so the error doesn't actually show up until this point. 1.333 + do_check_throws_nsIException(() => client1AsyncInput.available(), 1.334 + "NS_ERROR_CONNECTION_REFUSED"); 1.335 + 1.336 + client1AsyncInput.close(); 1.337 + client1.close(Cr.NS_OK); 1.338 + 1.339 + // Make the directory searchable, but make the socket inaccessible. 1.340 + dirName.permissions = allPermissions; 1.341 + socketName.permissions = 0; 1.342 + 1.343 + let client2 = socketTransportService.createUnixDomainTransport(socketName); 1.344 + let client2AsyncInput = client2.openInputStream(0, 0, 0).QueryInterface(Ci.nsIAsyncInputStream); 1.345 + client2AsyncInput.asyncWait(function (aStream) { 1.346 + do_print("called test_connect_permission's client2's onInputStreamReady"); 1.347 + log += '2'; 1.348 + 1.349 + do_check_throws_nsIException(() => client2AsyncInput.available(), 1.350 + "NS_ERROR_CONNECTION_REFUSED"); 1.351 + 1.352 + client2AsyncInput.close(); 1.353 + client2.close(Cr.NS_OK); 1.354 + 1.355 + // Now make everything accessible, and try one last time. 1.356 + socketName.permissions = allPermissions; 1.357 + 1.358 + client3 = socketTransportService.createUnixDomainTransport(socketName); 1.359 + 1.360 + let client3Output = client3.openOutputStream(0, 0, 0); 1.361 + client3Output.write("Hanratty", 8); 1.362 + 1.363 + let client3AsyncInput = client3.openInputStream(0, 0, 0).QueryInterface(Ci.nsIAsyncInputStream); 1.364 + client3AsyncInput.asyncWait(client3InputStreamReady, 0, 0, threadManager.currentThread); 1.365 + }, 0, 0, threadManager.currentThread); 1.366 + }, 0, 0, threadManager.currentThread); 1.367 + 1.368 + function socketAccepted(aServ, aTransport) { 1.369 + do_print("called test_connect_permission's onSocketAccepted"); 1.370 + log += 'a'; 1.371 + 1.372 + let serverInput = aTransport.openInputStream(0, 0, 0).QueryInterface(Ci.nsIAsyncInputStream); 1.373 + let serverOutput = aTransport.openOutputStream(0, 0, 0); 1.374 + 1.375 + serverInput.asyncWait(function (aStream) { 1.376 + do_print("called test_connect_permission's socketAccepted's onInputStreamReady"); 1.377 + log += 'i'; 1.378 + 1.379 + // Receive data from the client, and send back a response. 1.380 + let serverScriptableInput = new ScriptableInputStream(serverInput); 1.381 + do_check_eq(serverScriptableInput.readBytes(8), "Hanratty"); 1.382 + serverOutput.write("Ferlingatti", 11); 1.383 + }, 0, 0, threadManager.currentThread); 1.384 + } 1.385 + 1.386 + function client3InputStreamReady(aStream) { 1.387 + do_print("called client3's onInputStreamReady"); 1.388 + log += '3'; 1.389 + 1.390 + let client3Input = new ScriptableInputStream(aStream); 1.391 + 1.392 + do_check_eq(client3Input.readBytes(11), "Ferlingatti"); 1.393 + 1.394 + client3.close(Cr.NS_OK); 1.395 + server.close(); 1.396 + } 1.397 + 1.398 + function stopListening(aServ, aStatus) { 1.399 + do_print("called test_connect_permission's server's stopListening"); 1.400 + log += 's'; 1.401 + 1.402 + do_check_eq(log, '12ai3s'); 1.403 + 1.404 + run_next_test(); 1.405 + } 1.406 +} 1.407 + 1.408 +// Creating a socket with a long filename doesn't crash. 1.409 +function test_long_socket_name() 1.410 +{ 1.411 + let socketName = do_get_tempdir(); 1.412 + socketName.append(new Array(10000).join('long')); 1.413 + 1.414 + // Try to create a server socket with the long name. 1.415 + do_check_throws_nsIException(() => new UnixServerSocket(socketName, allPermissions, -1), 1.416 + "NS_ERROR_FILE_NAME_TOO_LONG"); 1.417 + 1.418 + // Try to connect to a socket with the long name. 1.419 + do_check_throws_nsIException(() => socketTransportService.createUnixDomainTransport(socketName), 1.420 + "NS_ERROR_FILE_NAME_TOO_LONG"); 1.421 + 1.422 + run_next_test(); 1.423 +} 1.424 + 1.425 +// Going offline should not shut down Unix domain sockets. 1.426 +function test_keep_when_offline() 1.427 +{ 1.428 + let log = ''; 1.429 + 1.430 + let socketName = do_get_tempdir(); 1.431 + socketName.append('keep-when-offline'); 1.432 + 1.433 + // Create a listening socket. 1.434 + let listener = new UnixServerSocket(socketName, allPermissions, -1); 1.435 + listener.asyncListen({ onSocketAccepted: onAccepted, onStopListening: onStopListening }); 1.436 + 1.437 + // Connect a client socket to the listening socket. 1.438 + let client = socketTransportService.createUnixDomainTransport(socketName); 1.439 + let clientOutput = client.openOutputStream(0, 0, 0); 1.440 + let clientInput = client.openInputStream(0, 0, 0); 1.441 + clientInput.asyncWait(clientReady, 0, 0, threadManager.currentThread); 1.442 + let clientScriptableInput = new ScriptableInputStream(clientInput); 1.443 + 1.444 + let server, serverInput, serverScriptableInput, serverOutput; 1.445 + 1.446 + // How many times has the server invited the client to go first? 1.447 + let count = 0; 1.448 + 1.449 + // The server accepted connection callback. 1.450 + function onAccepted(aListener, aServer) { 1.451 + do_print("test_keep_when_offline: onAccepted called"); 1.452 + log += 'a'; 1.453 + do_check_eq(aListener, listener); 1.454 + server = aServer; 1.455 + 1.456 + // Prepare to receive messages from the client. 1.457 + serverInput = server.openInputStream(0, 0, 0); 1.458 + serverInput.asyncWait(serverReady, 0, 0, threadManager.currentThread); 1.459 + serverScriptableInput = new ScriptableInputStream(serverInput); 1.460 + 1.461 + // Start a conversation with the client. 1.462 + serverOutput = server.openOutputStream(0, 0, 0); 1.463 + serverOutput.write("After you, Alphonse!", 20); 1.464 + count++; 1.465 + } 1.466 + 1.467 + // The client has seen its end of the socket close. 1.468 + function clientReady(aStream) { 1.469 + log += 'c'; 1.470 + do_print("test_keep_when_offline: clientReady called: " + log); 1.471 + do_check_eq(aStream, clientInput); 1.472 + 1.473 + // If the connection has been closed, end the conversation and stop listening. 1.474 + let available; 1.475 + try { 1.476 + available = clientInput.available(); 1.477 + } catch (ex) { 1.478 + do_check_instanceof(ex, Ci.nsIException); 1.479 + do_check_eq(ex.result, Cr.NS_BASE_STREAM_CLOSED); 1.480 + 1.481 + do_print("client received end-of-stream; closing client output stream"); 1.482 + log += ')'; 1.483 + 1.484 + client.close(Cr.NS_OK); 1.485 + 1.486 + // Now both output streams have been closed, and both input streams 1.487 + // have received the close notification. Stop listening for 1.488 + // connections. 1.489 + listener.close(); 1.490 + } 1.491 + 1.492 + if (available) { 1.493 + // Check the message from the server. 1.494 + do_check_eq(clientScriptableInput.readBytes(20), "After you, Alphonse!"); 1.495 + 1.496 + // Write our response to the server. 1.497 + clientOutput.write("No, after you, Gaston!", 22); 1.498 + 1.499 + // Ask to be called again, when more input arrives. 1.500 + clientInput.asyncWait(clientReady, 0, 0, threadManager.currentThread); 1.501 + } 1.502 + } 1.503 + 1.504 + function serverReady(aStream) { 1.505 + log += 's'; 1.506 + do_print("test_keep_when_offline: serverReady called: " + log); 1.507 + do_check_eq(aStream, serverInput); 1.508 + 1.509 + // Check the message from the client. 1.510 + do_check_eq(serverScriptableInput.readBytes(22), "No, after you, Gaston!"); 1.511 + 1.512 + // This should not shut things down: Unix domain sockets should 1.513 + // remain open in offline mode. 1.514 + if (count == 5) { 1.515 + IOService.offline = true; 1.516 + log += 'o'; 1.517 + } 1.518 + 1.519 + if (count < 10) { 1.520 + // Insist. 1.521 + serverOutput.write("After you, Alphonse!", 20); 1.522 + count++; 1.523 + 1.524 + // As long as the input stream is open, always ask to be called again 1.525 + // when more input arrives. 1.526 + serverInput.asyncWait(serverReady, 0, 0, threadManager.currentThread); 1.527 + } else if (count == 10) { 1.528 + // After sending ten times and receiving ten replies, we're not 1.529 + // going to send any more. Close the server's output stream; the 1.530 + // client's input stream should see this. 1.531 + do_print("closing server transport"); 1.532 + server.close(Cr.NS_OK); 1.533 + log += '('; 1.534 + } 1.535 + } 1.536 + 1.537 + // We have stopped listening. 1.538 + function onStopListening(aServ, aStatus) { 1.539 + do_print("test_keep_when_offline: onStopListening called"); 1.540 + log += 'L'; 1.541 + do_check_eq(log, 'acscscscscsocscscscscs(c)L'); 1.542 + 1.543 + do_check_eq(aServ, listener); 1.544 + do_check_eq(aStatus, Cr.NS_BINDING_ABORTED); 1.545 + 1.546 + run_next_test(); 1.547 + } 1.548 +}