1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/dom/network/tests/unit/test_tcpsocket.js Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,613 @@ 1.4 +/** 1.5 + * Test TCPSocket.js by creating an XPCOM-style server socket, then sending 1.6 + * data in both directions and making sure each side receives their data 1.7 + * correctly and with the proper events. 1.8 + * 1.9 + * This test is derived from netwerk/test/unit/test_socks.js, except we don't 1.10 + * involve a subprocess. 1.11 + * 1.12 + * Future work: 1.13 + * - SSL. see https://bugzilla.mozilla.org/show_bug.cgi?id=466524 1.14 + * https://bugzilla.mozilla.org/show_bug.cgi?id=662180 1.15 + * Alternatively, mochitests could be used. 1.16 + * - Testing overflow logic. 1.17 + * 1.18 + **/ 1.19 + 1.20 +const Cc = Components.classes; 1.21 +const Ci = Components.interfaces; 1.22 +const Cr = Components.results; 1.23 +const Cu = Components.utils; 1.24 +const CC = Components.Constructor; 1.25 + 1.26 +/** 1.27 + * 1.28 + * Constants 1.29 + * 1.30 + */ 1.31 + 1.32 +// Some binary data to send. 1.33 +const DATA_ARRAY = [0, 255, 254, 0, 1, 2, 3, 0, 255, 255, 254, 0], 1.34 + DATA_ARRAY_BUFFER = new ArrayBuffer(DATA_ARRAY.length), 1.35 + TYPED_DATA_ARRAY = new Uint8Array(DATA_ARRAY_BUFFER), 1.36 + HELLO_WORLD = "hlo wrld. ", 1.37 + BIG_ARRAY = new Array(65539), 1.38 + BIG_ARRAY_2 = new Array(65539); 1.39 + 1.40 +TYPED_DATA_ARRAY.set(DATA_ARRAY, 0); 1.41 + 1.42 +for (var i_big = 0; i_big < BIG_ARRAY.length; i_big++) { 1.43 + BIG_ARRAY[i_big] = Math.floor(Math.random() * 256); 1.44 + BIG_ARRAY_2[i_big] = Math.floor(Math.random() * 256); 1.45 +} 1.46 + 1.47 +const BIG_ARRAY_BUFFER = new ArrayBuffer(BIG_ARRAY.length), 1.48 + BIG_ARRAY_BUFFER_2 = new ArrayBuffer(BIG_ARRAY_2.length); 1.49 +const BIG_TYPED_ARRAY = new Uint8Array(BIG_ARRAY_BUFFER), 1.50 + BIG_TYPED_ARRAY_2 = new Uint8Array(BIG_ARRAY_BUFFER_2); 1.51 +BIG_TYPED_ARRAY.set(BIG_ARRAY); 1.52 +BIG_TYPED_ARRAY_2.set(BIG_ARRAY_2); 1.53 + 1.54 +const ServerSocket = CC("@mozilla.org/network/server-socket;1", 1.55 + "nsIServerSocket", 1.56 + "init"), 1.57 + InputStreamPump = CC("@mozilla.org/network/input-stream-pump;1", 1.58 + "nsIInputStreamPump", 1.59 + "init"), 1.60 + BinaryInputStream = CC("@mozilla.org/binaryinputstream;1", 1.61 + "nsIBinaryInputStream", 1.62 + "setInputStream"), 1.63 + BinaryOutputStream = CC("@mozilla.org/binaryoutputstream;1", 1.64 + "nsIBinaryOutputStream", 1.65 + "setOutputStream"), 1.66 + TCPSocket = new (CC("@mozilla.org/tcp-socket;1", 1.67 + "nsIDOMTCPSocket"))(); 1.68 + 1.69 +const gInChild = Cc["@mozilla.org/xre/app-info;1"].getService(Ci.nsIXULRuntime) 1.70 + .processType != Ci.nsIXULRuntime.PROCESS_TYPE_DEFAULT; 1.71 + 1.72 +Cu.import("resource://gre/modules/Services.jsm"); 1.73 + 1.74 +/** 1.75 + * 1.76 + * Helper functions 1.77 + * 1.78 + */ 1.79 + 1.80 +function get_platform() { 1.81 + var xulRuntime = Components.classes["@mozilla.org/xre/app-info;1"] 1.82 + .getService(Components.interfaces.nsIXULRuntime); 1.83 + return xulRuntime.OS; 1.84 +} 1.85 + 1.86 +function is_content() { 1.87 + return this._inChild = Cc["@mozilla.org/xre/app-info;1"].getService(Ci.nsIXULRuntime) 1.88 + .processType != Ci.nsIXULRuntime.PROCESS_TYPE_DEFAULT; 1.89 +} 1.90 + 1.91 +/** 1.92 + * Spin up a listening socket and associate at most one live, accepted socket 1.93 + * with ourselves. 1.94 + */ 1.95 +function TestServer() { 1.96 + this.listener = ServerSocket(-1, true, -1); 1.97 + do_print('server: listening on', this.listener.port); 1.98 + this.listener.asyncListen(this); 1.99 + 1.100 + this.binaryInput = null; 1.101 + this.input = null; 1.102 + this.binaryOutput = null; 1.103 + this.output = null; 1.104 + 1.105 + this.onconnect = null; 1.106 + this.ondata = null; 1.107 + this.onclose = null; 1.108 +} 1.109 + 1.110 +TestServer.prototype = { 1.111 + onSocketAccepted: function(socket, trans) { 1.112 + if (this.input) 1.113 + do_throw("More than one live connection!?"); 1.114 + 1.115 + do_print('server: got client connection'); 1.116 + this.input = trans.openInputStream(0, 0, 0); 1.117 + this.binaryInput = new BinaryInputStream(this.input); 1.118 + this.output = trans.openOutputStream(0, 0, 0); 1.119 + this.binaryOutput = new BinaryOutputStream(this.output); 1.120 + 1.121 + new InputStreamPump(this.input, -1, -1, 0, 0, false).asyncRead(this, null); 1.122 + 1.123 + if (this.onconnect) 1.124 + this.onconnect(); 1.125 + else 1.126 + do_throw("Received unexpected connection!"); 1.127 + }, 1.128 + 1.129 + onStopListening: function(socket) { 1.130 + }, 1.131 + 1.132 + onDataAvailable: function(request, context, inputStream, offset, count) { 1.133 + var readData = this.binaryInput.readByteArray(count); 1.134 + if (this.ondata) { 1.135 + try { 1.136 + this.ondata(readData); 1.137 + } catch(ex) { 1.138 + // re-throw if this is from do_throw 1.139 + if (ex === Cr.NS_ERROR_ABORT) 1.140 + throw ex; 1.141 + // log if there was a test problem 1.142 + do_print('Caught exception: ' + ex + '\n' + ex.stack); 1.143 + do_throw('test is broken; bad ondata handler; see above'); 1.144 + } 1.145 + } else { 1.146 + do_throw('Received ' + count + ' bytes of unexpected data!'); 1.147 + } 1.148 + }, 1.149 + 1.150 + onStartRequest: function(request, context) { 1.151 + }, 1.152 + 1.153 + onStopRequest: function(request, context, status) { 1.154 + if (this.onclose) 1.155 + this.onclose(); 1.156 + else 1.157 + do_throw("Received unexpected close!"); 1.158 + }, 1.159 + 1.160 + close: function() { 1.161 + this.binaryInput.close(); 1.162 + this.binaryOutput.close(); 1.163 + }, 1.164 + 1.165 + /** 1.166 + * Forget about the socket we knew about before. 1.167 + */ 1.168 + reset: function() { 1.169 + this.binaryInput = null; 1.170 + this.input = null; 1.171 + this.binaryOutput = null; 1.172 + this.output = null; 1.173 + }, 1.174 +}; 1.175 + 1.176 +function makeSuccessCase(name) { 1.177 + return function() { 1.178 + do_print('got expected: ' + name); 1.179 + run_next_test(); 1.180 + }; 1.181 +} 1.182 + 1.183 +function makeJointSuccess(names) { 1.184 + let funcs = {}, successCount = 0; 1.185 + names.forEach(function(name) { 1.186 + funcs[name] = function() { 1.187 + do_print('got expected: ' + name); 1.188 + if (++successCount === names.length) 1.189 + run_next_test(); 1.190 + }; 1.191 + }); 1.192 + return funcs; 1.193 +} 1.194 + 1.195 +function makeFailureCase(name) { 1.196 + return function() { 1.197 + let argstr; 1.198 + if (arguments.length) { 1.199 + argstr = '(args: ' + 1.200 + Array.map(arguments, function(x) { return x.data + ""; }).join(" ") + ')'; 1.201 + } 1.202 + else { 1.203 + argstr = '(no arguments)'; 1.204 + } 1.205 + do_throw('got unexpected: ' + name + ' ' + argstr); 1.206 + }; 1.207 +} 1.208 + 1.209 +function makeExpectData(name, expectedData, fromEvent, callback) { 1.210 + let dataBuffer = fromEvent ? null : [], done = false; 1.211 + let dataBufferView = null; 1.212 + return function(receivedData) { 1.213 + if (receivedData.data) { 1.214 + receivedData = receivedData.data; 1.215 + } 1.216 + let recvLength = receivedData.byteLength !== undefined ? 1.217 + receivedData.byteLength : receivedData.length; 1.218 + 1.219 + if (fromEvent) { 1.220 + if (dataBuffer) { 1.221 + let newBuffer = new ArrayBuffer(dataBuffer.byteLength + recvLength); 1.222 + let newBufferView = new Uint8Array(newBuffer); 1.223 + newBufferView.set(dataBufferView, 0); 1.224 + newBufferView.set(receivedData, dataBuffer.byteLength); 1.225 + dataBuffer = newBuffer; 1.226 + dataBufferView = newBufferView; 1.227 + } 1.228 + else { 1.229 + dataBuffer = receivedData; 1.230 + dataBufferView = new Uint8Array(dataBuffer); 1.231 + } 1.232 + } 1.233 + else { 1.234 + dataBuffer = dataBuffer.concat(receivedData); 1.235 + } 1.236 + do_print(name + ' received ' + recvLength + ' bytes'); 1.237 + 1.238 + if (done) 1.239 + do_throw(name + ' Received data event when already done!'); 1.240 + 1.241 + let dataView = dataBuffer.byteLength !== undefined ? new Uint8Array(dataBuffer) : dataBuffer; 1.242 + if (dataView.length >= expectedData.length) { 1.243 + // check the bytes are equivalent 1.244 + for (let i = 0; i < expectedData.length; i++) { 1.245 + if (dataView[i] !== expectedData[i]) { 1.246 + do_throw(name + ' Received mismatched character at position ' + i); 1.247 + } 1.248 + } 1.249 + if (dataView.length > expectedData.length) 1.250 + do_throw(name + ' Received ' + dataView.length + ' bytes but only expected ' + 1.251 + expectedData.length + ' bytes.'); 1.252 + 1.253 + done = true; 1.254 + if (callback) { 1.255 + callback(); 1.256 + } else { 1.257 + run_next_test(); 1.258 + } 1.259 + } 1.260 + }; 1.261 +} 1.262 + 1.263 +var server = null, sock = null, failure_drain = null; 1.264 + 1.265 +/** 1.266 + * 1.267 + * Test functions 1.268 + * 1.269 + */ 1.270 + 1.271 +/** 1.272 + * Connect the socket to the server. This test is added as the first 1.273 + * test, and is also added after every test which results in the socket 1.274 + * being closed. 1.275 + */ 1.276 + 1.277 +function connectSock() { 1.278 + server.reset(); 1.279 + var yayFuncs = makeJointSuccess(['serveropen', 'clientopen']); 1.280 + 1.281 + sock = TCPSocket.open( 1.282 + '127.0.0.1', server.listener.port, 1.283 + { binaryType: 'arraybuffer' }); 1.284 + 1.285 + sock.onopen = yayFuncs.clientopen; 1.286 + sock.ondrain = null; 1.287 + sock.ondata = makeFailureCase('data'); 1.288 + sock.onerror = makeFailureCase('error'); 1.289 + sock.onclose = makeFailureCase('close'); 1.290 + 1.291 + server.onconnect = yayFuncs.serveropen; 1.292 + server.ondata = makeFailureCase('serverdata'); 1.293 + server.onclose = makeFailureCase('serverclose'); 1.294 +} 1.295 + 1.296 +/** 1.297 + * Test that sending a small amount of data works, and that buffering 1.298 + * does not take place for this small amount of data. 1.299 + */ 1.300 + 1.301 +function sendData() { 1.302 + server.ondata = makeExpectData('serverdata', DATA_ARRAY); 1.303 + if (!sock.send(DATA_ARRAY_BUFFER)) { 1.304 + do_throw("send should not have buffered such a small amount of data"); 1.305 + } 1.306 +} 1.307 + 1.308 +/** 1.309 + * Test that sending a large amount of data works, that buffering 1.310 + * takes place (send returns true), and that ondrain is called once 1.311 + * the data has been sent. 1.312 + */ 1.313 + 1.314 +function sendBig() { 1.315 + var yays = makeJointSuccess(['serverdata', 'clientdrain']), 1.316 + amount = 0; 1.317 + 1.318 + server.ondata = function (data) { 1.319 + amount += data.length; 1.320 + if (amount === BIG_TYPED_ARRAY.length) { 1.321 + yays.serverdata(); 1.322 + } 1.323 + }; 1.324 + sock.ondrain = function(evt) { 1.325 + if (sock.bufferedAmount) { 1.326 + do_throw("sock.bufferedAmount was > 0 in ondrain"); 1.327 + } 1.328 + yays.clientdrain(evt); 1.329 + } 1.330 + if (sock.send(BIG_ARRAY_BUFFER)) { 1.331 + do_throw("expected sock.send to return false on large buffer send"); 1.332 + } 1.333 +} 1.334 + 1.335 +/** 1.336 + * Test that data sent from the server correctly fires the ondata 1.337 + * callback on the client side. 1.338 + */ 1.339 + 1.340 +function receiveData() { 1.341 + server.ondata = makeFailureCase('serverdata'); 1.342 + sock.ondata = makeExpectData('data', DATA_ARRAY, true); 1.343 + 1.344 + server.binaryOutput.writeByteArray(DATA_ARRAY, DATA_ARRAY.length); 1.345 +} 1.346 + 1.347 +/** 1.348 + * Test that when the server closes the connection, the onclose callback 1.349 + * is fired on the client side. 1.350 + */ 1.351 + 1.352 +function serverCloses() { 1.353 + // we don't really care about the server's close event, but we do want to 1.354 + // make sure it happened for sequencing purposes. 1.355 + var yayFuncs = makeJointSuccess(['clientclose', 'serverclose']); 1.356 + sock.ondata = makeFailureCase('data'); 1.357 + sock.onclose = yayFuncs.clientclose; 1.358 + server.onclose = yayFuncs.serverclose; 1.359 + 1.360 + server.close(); 1.361 +} 1.362 + 1.363 +/** 1.364 + * Test that when the client closes the connection, the onclose callback 1.365 + * is fired on the server side. 1.366 + */ 1.367 + 1.368 +function clientCloses() { 1.369 + // we want to make sure the server heard the close and also that the client's 1.370 + // onclose event fired for consistency. 1.371 + var yayFuncs = makeJointSuccess(['clientclose', 'serverclose']); 1.372 + server.onclose = yayFuncs.serverclose; 1.373 + sock.onclose = yayFuncs.clientclose; 1.374 + 1.375 + sock.close(); 1.376 +} 1.377 + 1.378 +/** 1.379 + * Send a large amount of data and immediately call close 1.380 + */ 1.381 + 1.382 +function bufferedClose() { 1.383 + var yays = makeJointSuccess(['serverdata', 'clientclose', 'serverclose']); 1.384 + server.ondata = makeExpectData( 1.385 + "ondata", BIG_TYPED_ARRAY, false, yays.serverdata); 1.386 + server.onclose = yays.serverclose; 1.387 + sock.onclose = yays.clientclose; 1.388 + sock.send(BIG_ARRAY_BUFFER); 1.389 + sock.close(); 1.390 +} 1.391 + 1.392 +/** 1.393 + * Connect to a port we know is not listening so an error is assured, 1.394 + * and make sure that onerror and onclose are fired on the client side. 1.395 + */ 1.396 + 1.397 +function badConnect() { 1.398 + // There's probably nothing listening on tcp port 2. 1.399 + sock = TCPSocket.open('127.0.0.1', 2); 1.400 + 1.401 + sock.onopen = makeFailureCase('open'); 1.402 + sock.ondata = makeFailureCase('data'); 1.403 + 1.404 + let success = makeSuccessCase('error'); 1.405 + let gotError = false; 1.406 + sock.onerror = function(event) { 1.407 + do_check_eq(event.data.name, 'ConnectionRefusedError'); 1.408 + gotError = true; 1.409 + }; 1.410 + sock.onclose = function() { 1.411 + if (!gotError) 1.412 + do_throw('got close without error!'); 1.413 + else 1.414 + success(); 1.415 + }; 1.416 +} 1.417 + 1.418 +/** 1.419 + * Test that calling send with enough data to buffer causes ondrain to 1.420 + * be invoked once the data has been sent, and then test that calling send 1.421 + * and buffering again causes ondrain to be fired again. 1.422 + */ 1.423 + 1.424 +function drainTwice() { 1.425 + let yays = makeJointSuccess( 1.426 + ['ondrain', 'ondrain2', 1.427 + 'ondata', 'ondata2', 1.428 + 'serverclose', 'clientclose']); 1.429 + let ondrainCalled = false, 1.430 + ondataCalled = false; 1.431 + 1.432 + function maybeSendNextData() { 1.433 + if (!ondrainCalled || !ondataCalled) { 1.434 + // make sure server got data and client got ondrain. 1.435 + return; 1.436 + } 1.437 + 1.438 + server.ondata = makeExpectData( 1.439 + "ondata2", BIG_TYPED_ARRAY_2, false, yays.ondata2); 1.440 + 1.441 + sock.ondrain = yays.ondrain2; 1.442 + 1.443 + if (sock.send(BIG_ARRAY_BUFFER_2)) { 1.444 + do_throw("sock.send(BIG_TYPED_ARRAY_2) did not return false to indicate buffering"); 1.445 + } 1.446 + 1.447 + sock.close(); 1.448 + } 1.449 + 1.450 + function clientOndrain() { 1.451 + yays.ondrain(); 1.452 + ondrainCalled = true; 1.453 + maybeSendNextData(); 1.454 + } 1.455 + 1.456 + function serverSideCallback() { 1.457 + yays.ondata(); 1.458 + ondataCalled = true; 1.459 + maybeSendNextData(); 1.460 + } 1.461 + 1.462 + server.onclose = yays.serverclose; 1.463 + server.ondata = makeExpectData( 1.464 + "ondata", BIG_TYPED_ARRAY, false, serverSideCallback); 1.465 + 1.466 + sock.onclose = yays.clientclose; 1.467 + sock.ondrain = clientOndrain; 1.468 + 1.469 + if (sock.send(BIG_ARRAY_BUFFER)) { 1.470 + throw new Error("sock.send(BIG_TYPED_ARRAY) did not return false to indicate buffering"); 1.471 + } 1.472 +} 1.473 + 1.474 +function cleanup() { 1.475 + do_print("Cleaning up"); 1.476 + sock.close(); 1.477 + if (!gInChild) 1.478 + Services.prefs.clearUserPref('dom.mozTCPSocket.enabled'); 1.479 + run_next_test(); 1.480 +} 1.481 + 1.482 +/** 1.483 + * Test that calling send with enough data to buffer twice in a row without 1.484 + * waiting for ondrain still results in ondrain being invoked at least once. 1.485 + */ 1.486 + 1.487 +function bufferTwice() { 1.488 + let yays = makeJointSuccess( 1.489 + ['ondata', 'ondrain', 'serverclose', 'clientclose']); 1.490 + 1.491 + let double_array = new Uint8Array(BIG_ARRAY.concat(BIG_ARRAY_2)); 1.492 + server.ondata = makeExpectData( 1.493 + "ondata", double_array, false, yays.ondata); 1.494 + 1.495 + server.onclose = yays.serverclose; 1.496 + sock.onclose = yays.clientclose; 1.497 + 1.498 + sock.ondrain = function () { 1.499 + sock.close(); 1.500 + yays.ondrain(); 1.501 + } 1.502 + 1.503 + if (sock.send(BIG_ARRAY_BUFFER)) { 1.504 + throw new Error("sock.send(BIG_TYPED_ARRAY) did not return false to indicate buffering"); 1.505 + } 1.506 + if (sock.send(BIG_ARRAY_BUFFER_2)) { 1.507 + throw new Error("sock.send(BIG_TYPED_ARRAY_2) did not return false to indicate buffering on second synchronous call to send"); 1.508 + } 1.509 +} 1.510 + 1.511 +// Test child behavior when child thinks it's buffering but parent doesn't 1.512 +// buffer. 1.513 +// 1. set bufferedAmount of content socket to a value that will make next 1.514 +// send() call return false. 1.515 +// 2. send a small data to make send() return false, but it won't make 1.516 +// parent buffer. 1.517 +// 3. we should get a ondrain. 1.518 +function childbuffered() { 1.519 + let yays = makeJointSuccess(['ondrain', 'serverdata', 1.520 + 'clientclose', 'serverclose']); 1.521 + sock.ondrain = function() { 1.522 + yays.ondrain(); 1.523 + sock.close(); 1.524 + }; 1.525 + 1.526 + server.ondata = makeExpectData( 1.527 + 'ondata', DATA_ARRAY, false, yays.serverdata); 1.528 + 1.529 + let internalSocket = sock.QueryInterface(Ci.nsITCPSocketInternal); 1.530 + internalSocket.updateBufferedAmount(65535, // almost reach buffering threshold 1.531 + 0); 1.532 + if (sock.send(DATA_ARRAY_BUFFER)) { 1.533 + do_throw("expected sock.send to return false."); 1.534 + } 1.535 + 1.536 + sock.onclose = yays.clientclose; 1.537 + server.onclose = yays.serverclose; 1.538 +} 1.539 + 1.540 +// Test child's behavior when send() of child return true but parent buffers 1.541 +// data. 1.542 +// 1. send BIG_ARRAY to make parent buffer. This would make child wait for 1.543 +// drain as well. 1.544 +// 2. set child's bufferedAmount to zero, so child will no longer wait for 1.545 +// drain but parent will dispatch a drain event. 1.546 +// 3. wait for 1 second, to make sure there's no ondrain event dispatched in 1.547 +// child. 1.548 +function childnotbuffered() { 1.549 + let yays = makeJointSuccess(['serverdata', 'clientclose', 'serverclose']); 1.550 + server.ondata = makeExpectData('ondata', BIG_ARRAY, false, yays.serverdata); 1.551 + if (sock.send(BIG_ARRAY_BUFFER)) { 1.552 + do_throw("sock.send(BIG_TYPED_ARRAY) did not return false to indicate buffering"); 1.553 + } 1.554 + let internalSocket = sock.QueryInterface(Ci.nsITCPSocketInternal); 1.555 + internalSocket.updateBufferedAmount(0, // setting zero will clear waitForDrain in sock. 1.556 + 1); 1.557 + 1.558 + // shouldn't get ondrain, even after parent have cleared its buffer. 1.559 + sock.ondrain = makeFailureCase('drain'); 1.560 + sock.onclose = yays.clientclose; 1.561 + server.onclose = yays.serverclose; 1.562 + do_timeout(1000, function() { 1.563 + sock.close(); 1.564 + }); 1.565 +}; 1.566 + 1.567 +// - connect, data and events work both ways 1.568 +add_test(connectSock); 1.569 +add_test(sendData); 1.570 +add_test(sendBig); 1.571 +add_test(receiveData); 1.572 +// - server closes on us 1.573 +add_test(serverCloses); 1.574 + 1.575 +// - connect, we close on the server 1.576 +add_test(connectSock); 1.577 +add_test(clientCloses); 1.578 + 1.579 +// - connect, buffer, close 1.580 +add_test(connectSock); 1.581 +add_test(bufferedClose); 1.582 + 1.583 +if (get_platform() !== "Darwin") { 1.584 + // This test intermittently fails way too often on OS X, for unknown reasons. 1.585 + // Please, diagnose and fix it if you can. 1.586 + // - get an error on an attempt to connect to a non-listening port 1.587 + add_test(badConnect); 1.588 +} 1.589 + 1.590 +// send a buffer, get a drain, send a buffer, get a drain 1.591 +add_test(connectSock); 1.592 +add_test(drainTwice); 1.593 + 1.594 +// send a buffer, get a drain, send a buffer, get a drain 1.595 +add_test(connectSock); 1.596 +add_test(bufferTwice); 1.597 + 1.598 +if (is_content()) { 1.599 + add_test(connectSock); 1.600 + add_test(childnotbuffered); 1.601 + 1.602 + add_test(connectSock); 1.603 + add_test(childbuffered); 1.604 +} 1.605 + 1.606 +// clean up 1.607 +add_test(cleanup); 1.608 + 1.609 +function run_test() { 1.610 + if (!gInChild) 1.611 + Services.prefs.setBoolPref('dom.mozTCPSocket.enabled', true); 1.612 + 1.613 + server = new TestServer(); 1.614 + 1.615 + run_next_test(); 1.616 +}