netwerk/test/unit/test_unix_domain.js

Wed, 31 Dec 2014 06:55:46 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:55:46 +0100
changeset 1
ca08bd8f51b2
permissions
-rw-r--r--

Added tag TORBROWSER_REPLICA for changeset 6474c204b198

michael@0 1 // Exercise Unix domain sockets.
michael@0 2
michael@0 3 const CC = Components.Constructor;
michael@0 4
michael@0 5 const UnixServerSocket = CC("@mozilla.org/network/server-socket;1",
michael@0 6 "nsIServerSocket",
michael@0 7 "initWithFilename");
michael@0 8
michael@0 9 const ScriptableInputStream = CC("@mozilla.org/scriptableinputstream;1",
michael@0 10 "nsIScriptableInputStream",
michael@0 11 "init");
michael@0 12
michael@0 13 const IOService = Cc["@mozilla.org/network/io-service;1"]
michael@0 14 .getService(Ci.nsIIOService);
michael@0 15 const socketTransportService = Cc["@mozilla.org/network/socket-transport-service;1"]
michael@0 16 .getService(Ci.nsISocketTransportService);
michael@0 17
michael@0 18 const threadManager = Cc["@mozilla.org/thread-manager;1"].getService();
michael@0 19
michael@0 20 const allPermissions = parseInt("777", 8);
michael@0 21
michael@0 22 function run_test()
michael@0 23 {
michael@0 24 // If we're on Windows, simply check for graceful failure.
michael@0 25 if ("@mozilla.org/windows-registry-key;1" in Cc) {
michael@0 26 test_not_supported();
michael@0 27 return;
michael@0 28 }
michael@0 29
michael@0 30 add_test(test_echo);
michael@0 31 add_test(test_name_too_long);
michael@0 32 add_test(test_no_directory);
michael@0 33 add_test(test_no_such_socket);
michael@0 34 add_test(test_address_in_use);
michael@0 35 add_test(test_file_in_way);
michael@0 36 add_test(test_create_permission);
michael@0 37 add_test(test_connect_permission);
michael@0 38 add_test(test_long_socket_name);
michael@0 39 add_test(test_keep_when_offline);
michael@0 40
michael@0 41 run_next_test();
michael@0 42 }
michael@0 43
michael@0 44 // Check that creating a Unix domain socket fails gracefully on Windows.
michael@0 45 function test_not_supported()
michael@0 46 {
michael@0 47 let socketName = do_get_tempdir();
michael@0 48 socketName.append('socket');
michael@0 49 do_print("creating socket: " + socketName.path);
michael@0 50
michael@0 51 do_check_throws_nsIException(() => new UnixServerSocket(socketName, allPermissions, -1),
michael@0 52 "NS_ERROR_SOCKET_ADDRESS_NOT_SUPPORTED");
michael@0 53
michael@0 54 do_check_throws_nsIException(() => socketTransportService.createUnixDomainTransport(socketName),
michael@0 55 "NS_ERROR_SOCKET_ADDRESS_NOT_SUPPORTED");
michael@0 56 }
michael@0 57
michael@0 58 // Actually exchange data with Unix domain sockets.
michael@0 59 function test_echo()
michael@0 60 {
michael@0 61 let log = '';
michael@0 62
michael@0 63 let socketName = do_get_tempdir();
michael@0 64 socketName.append('socket');
michael@0 65
michael@0 66 // Create a server socket, listening for connections.
michael@0 67 do_print("creating socket: " + socketName.path);
michael@0 68 let server = new UnixServerSocket(socketName, allPermissions, -1);
michael@0 69 server.asyncListen({
michael@0 70 onSocketAccepted: function(aServ, aTransport) {
michael@0 71 do_print("called test_echo's onSocketAccepted");
michael@0 72 log += 'a';
michael@0 73
michael@0 74 do_check_eq(aServ, server);
michael@0 75
michael@0 76 let connection = aTransport;
michael@0 77
michael@0 78 // Check the server socket's self address.
michael@0 79 let connectionSelfAddr = connection.getScriptableSelfAddr();
michael@0 80 do_check_eq(connectionSelfAddr.family, Ci.nsINetAddr.FAMILY_LOCAL);
michael@0 81 do_check_eq(connectionSelfAddr.address, socketName.path);
michael@0 82
michael@0 83 // The client socket is anonymous, so the server transport should
michael@0 84 // have an empty peer address.
michael@0 85 do_check_eq(connection.host, '');
michael@0 86 do_check_eq(connection.port, 0);
michael@0 87 let connectionPeerAddr = connection.getScriptablePeerAddr();
michael@0 88 do_check_eq(connectionPeerAddr.family, Ci.nsINetAddr.FAMILY_LOCAL);
michael@0 89 do_check_eq(connectionPeerAddr.address, '');
michael@0 90
michael@0 91 let serverAsyncInput = connection.openInputStream(0, 0, 0).QueryInterface(Ci.nsIAsyncInputStream);
michael@0 92 let serverOutput = connection.openOutputStream(0, 0, 0);
michael@0 93
michael@0 94 serverAsyncInput.asyncWait(function (aStream) {
michael@0 95 do_print("called test_echo's server's onInputStreamReady");
michael@0 96 let serverScriptableInput = new ScriptableInputStream(aStream);
michael@0 97
michael@0 98 // Receive data from the client, and send back a response.
michael@0 99 do_check_eq(serverScriptableInput.readBytes(17), "Mervyn Murgatroyd");
michael@0 100 do_print("server has read message from client");
michael@0 101 serverOutput.write("Ruthven Murgatroyd", 18);
michael@0 102 do_print("server has written to client");
michael@0 103 }, 0, 0, threadManager.currentThread);
michael@0 104 },
michael@0 105
michael@0 106 onStopListening: function(aServ, aStatus) {
michael@0 107 do_print("called test_echo's onStopListening");
michael@0 108 log += 's';
michael@0 109
michael@0 110 do_check_eq(aServ, server);
michael@0 111 do_check_eq(log, 'acs');
michael@0 112
michael@0 113 run_next_test();
michael@0 114 }
michael@0 115 });
michael@0 116
michael@0 117 // Create a client socket, and connect to the server.
michael@0 118 let client = socketTransportService.createUnixDomainTransport(socketName);
michael@0 119 do_check_eq(client.host, socketName.path);
michael@0 120 do_check_eq(client.port, 0);
michael@0 121
michael@0 122 let clientAsyncInput = client.openInputStream(0, 0, 0).QueryInterface(Ci.nsIAsyncInputStream);
michael@0 123 let clientInput = new ScriptableInputStream(clientAsyncInput);
michael@0 124 let clientOutput = client.openOutputStream(0, 0, 0);
michael@0 125
michael@0 126 clientOutput.write("Mervyn Murgatroyd", 17);
michael@0 127 do_print("client has written to server");
michael@0 128
michael@0 129 clientAsyncInput.asyncWait(function (aStream) {
michael@0 130 do_print("called test_echo's client's onInputStreamReady");
michael@0 131 log += 'c';
michael@0 132
michael@0 133 do_check_eq(aStream, clientAsyncInput);
michael@0 134
michael@0 135 // Now that the connection has been established, we can check the
michael@0 136 // transport's self and peer addresses.
michael@0 137 let clientSelfAddr = client.getScriptableSelfAddr();
michael@0 138 do_check_eq(clientSelfAddr.family, Ci.nsINetAddr.FAMILY_LOCAL);
michael@0 139 do_check_eq(clientSelfAddr.address, '');
michael@0 140
michael@0 141 do_check_eq(client.host, socketName.path); // re-check, but hey
michael@0 142 let clientPeerAddr = client.getScriptablePeerAddr();
michael@0 143 do_check_eq(clientPeerAddr.family, Ci.nsINetAddr.FAMILY_LOCAL);
michael@0 144 do_check_eq(clientPeerAddr.address, socketName.path);
michael@0 145
michael@0 146 do_check_eq(clientInput.readBytes(18), "Ruthven Murgatroyd");
michael@0 147 do_print("client has read message from server");
michael@0 148
michael@0 149 server.close();
michael@0 150 }, 0, 0, threadManager.currentThread);
michael@0 151 }
michael@0 152
michael@0 153 // Create client and server sockets using a path that's too long.
michael@0 154 function test_name_too_long()
michael@0 155 {
michael@0 156 let socketName = do_get_tempdir();
michael@0 157 // The length limits on all the systems NSPR supports are a bit past 100.
michael@0 158 socketName.append(new Array(1000).join('x'));
michael@0 159
michael@0 160 // The length must be checked before we ever make any system calls --- we
michael@0 161 // have to create the sockaddr first --- so it's unambiguous which error
michael@0 162 // we should get here.
michael@0 163
michael@0 164 do_check_throws_nsIException(() => new UnixServerSocket(socketName, 0, -1),
michael@0 165 "NS_ERROR_FILE_NAME_TOO_LONG");
michael@0 166
michael@0 167 // Unlike most other client socket errors, this one gets reported
michael@0 168 // immediately, as we can't even initialize the sockaddr with the given
michael@0 169 // name.
michael@0 170 do_check_throws_nsIException(() => socketTransportService.createUnixDomainTransport(socketName),
michael@0 171 "NS_ERROR_FILE_NAME_TOO_LONG");
michael@0 172
michael@0 173 run_next_test();
michael@0 174 }
michael@0 175
michael@0 176 // Try creating a socket in a directory that doesn't exist.
michael@0 177 function test_no_directory()
michael@0 178 {
michael@0 179 let socketName = do_get_tempdir();
michael@0 180 socketName.append('directory-that-does-not-exist');
michael@0 181 socketName.append('socket');
michael@0 182
michael@0 183 do_check_throws_nsIException(() => new UnixServerSocket(socketName, 0, -1),
michael@0 184 "NS_ERROR_FILE_NOT_FOUND");
michael@0 185
michael@0 186 run_next_test();
michael@0 187 }
michael@0 188
michael@0 189 // Try connecting to a server socket that isn't there.
michael@0 190 function test_no_such_socket()
michael@0 191 {
michael@0 192 let socketName = do_get_tempdir();
michael@0 193 socketName.append('nonexistent-socket');
michael@0 194
michael@0 195 let client = socketTransportService.createUnixDomainTransport(socketName);
michael@0 196 let clientAsyncInput = client.openInputStream(0, 0, 0).QueryInterface(Ci.nsIAsyncInputStream);
michael@0 197 clientAsyncInput.asyncWait(function (aStream) {
michael@0 198 do_print("called test_no_such_socket's onInputStreamReady");
michael@0 199
michael@0 200 do_check_eq(aStream, clientAsyncInput);
michael@0 201
michael@0 202 // nsISocketTransport puts off actually creating sockets as long as
michael@0 203 // possible, so the error in connecting doesn't actually show up until
michael@0 204 // this point.
michael@0 205 do_check_throws_nsIException(() => clientAsyncInput.available(),
michael@0 206 "NS_ERROR_FILE_NOT_FOUND");
michael@0 207
michael@0 208 clientAsyncInput.close();
michael@0 209 client.close(Cr.NS_OK);
michael@0 210
michael@0 211 run_next_test();
michael@0 212 }, 0, 0, threadManager.currentThread);
michael@0 213 }
michael@0 214
michael@0 215 // Creating a socket with a name that another socket is already using is an
michael@0 216 // error.
michael@0 217 function test_address_in_use()
michael@0 218 {
michael@0 219 let socketName = do_get_tempdir();
michael@0 220 socketName.append('socket-in-use');
michael@0 221
michael@0 222 // Create one server socket.
michael@0 223 let server = new UnixServerSocket(socketName, allPermissions, -1);
michael@0 224
michael@0 225 // Now try to create another with the same name.
michael@0 226 do_check_throws_nsIException(() => new UnixServerSocket(socketName, allPermissions, -1),
michael@0 227 "NS_ERROR_SOCKET_ADDRESS_IN_USE");
michael@0 228
michael@0 229 run_next_test();
michael@0 230 }
michael@0 231
michael@0 232 // Creating a socket with a name that is already a file is an error.
michael@0 233 function test_file_in_way()
michael@0 234 {
michael@0 235 let socketName = do_get_tempdir();
michael@0 236 socketName.append('file_in_way');
michael@0 237
michael@0 238 // Create a file with the given name.
michael@0 239 socketName.create(Ci.nsIFile.NORMAL_FILE_TYPE, allPermissions);
michael@0 240
michael@0 241 // Try to create a socket with the same name.
michael@0 242 do_check_throws_nsIException(() => new UnixServerSocket(socketName, allPermissions, -1),
michael@0 243 "NS_ERROR_SOCKET_ADDRESS_IN_USE");
michael@0 244
michael@0 245 // Try to create a socket under a name that uses that as a parent directory.
michael@0 246 socketName.append('socket');
michael@0 247 do_check_throws_nsIException(() => new UnixServerSocket(socketName, 0, -1),
michael@0 248 "NS_ERROR_FILE_NOT_DIRECTORY");
michael@0 249
michael@0 250 run_next_test();
michael@0 251 }
michael@0 252
michael@0 253 // It is not permitted to create a socket in a directory which we are not
michael@0 254 // permitted to execute, or create files in.
michael@0 255 function test_create_permission()
michael@0 256 {
michael@0 257 let dirName = do_get_tempdir();
michael@0 258 dirName.append('unfriendly');
michael@0 259
michael@0 260 let socketName = dirName.clone();
michael@0 261 socketName.append('socket');
michael@0 262
michael@0 263 // The test harness has difficulty cleaning things up if we don't make
michael@0 264 // everything writable before we're done.
michael@0 265 try {
michael@0 266 // Create a directory which we are not permitted to search.
michael@0 267 dirName.create(Ci.nsIFile.DIRECTORY_TYPE, 0);
michael@0 268
michael@0 269 // Try to create a socket in that directory. Because Linux returns EACCES
michael@0 270 // when a 'connect' fails because of a local firewall rule,
michael@0 271 // nsIServerSocket returns NS_ERROR_CONNECTION_REFUSED in this case.
michael@0 272 do_check_throws_nsIException(() => new UnixServerSocket(socketName, allPermissions, -1),
michael@0 273 "NS_ERROR_CONNECTION_REFUSED");
michael@0 274
michael@0 275 // Grant read and execute permission, but not write permission on the directory.
michael@0 276 dirName.permissions = parseInt("0555", 8);
michael@0 277
michael@0 278 // This should also fail; we need write permission.
michael@0 279 do_check_throws_nsIException(() => new UnixServerSocket(socketName, allPermissions, -1),
michael@0 280 "NS_ERROR_CONNECTION_REFUSED");
michael@0 281
michael@0 282 } finally {
michael@0 283 // Make the directory writable, so the test harness can clean it up.
michael@0 284 dirName.permissions = allPermissions;
michael@0 285 }
michael@0 286
michael@0 287 // This should succeed, since we now have all the permissions on the
michael@0 288 // directory we could want.
michael@0 289 do_check_instanceof(new UnixServerSocket(socketName, allPermissions, -1),
michael@0 290 Ci.nsIServerSocket);
michael@0 291
michael@0 292 run_next_test();
michael@0 293 }
michael@0 294
michael@0 295 // To connect to a Unix domain socket, we need search permission on the
michael@0 296 // directories containing it, and some kind of permission or other on the
michael@0 297 // socket itself.
michael@0 298 function test_connect_permission()
michael@0 299 {
michael@0 300 // This test involves a lot of callbacks, but they're written out so that
michael@0 301 // the actual control flow proceeds from top to bottom.
michael@0 302 let log = '';
michael@0 303
michael@0 304 // Create a directory which we are permitted to search - at first.
michael@0 305 let dirName = do_get_tempdir();
michael@0 306 dirName.append('inhospitable');
michael@0 307 dirName.create(Ci.nsIFile.DIRECTORY_TYPE, allPermissions);
michael@0 308
michael@0 309 let socketName = dirName.clone();
michael@0 310 socketName.append('socket');
michael@0 311
michael@0 312 // Create a server socket in that directory, listening for connections,
michael@0 313 // and accessible.
michael@0 314 let server = new UnixServerSocket(socketName, allPermissions, -1);
michael@0 315 server.asyncListen({ onSocketAccepted: socketAccepted, onStopListening: stopListening });
michael@0 316
michael@0 317 // Make the directory unsearchable.
michael@0 318 dirName.permissions = 0;
michael@0 319
michael@0 320 let client3;
michael@0 321
michael@0 322 let client1 = socketTransportService.createUnixDomainTransport(socketName);
michael@0 323 let client1AsyncInput = client1.openInputStream(0, 0, 0).QueryInterface(Ci.nsIAsyncInputStream);
michael@0 324 client1AsyncInput.asyncWait(function (aStream) {
michael@0 325 do_print("called test_connect_permission's client1's onInputStreamReady");
michael@0 326 log += '1';
michael@0 327
michael@0 328 // nsISocketTransport puts off actually creating sockets as long as
michael@0 329 // possible, so the error doesn't actually show up until this point.
michael@0 330 do_check_throws_nsIException(() => client1AsyncInput.available(),
michael@0 331 "NS_ERROR_CONNECTION_REFUSED");
michael@0 332
michael@0 333 client1AsyncInput.close();
michael@0 334 client1.close(Cr.NS_OK);
michael@0 335
michael@0 336 // Make the directory searchable, but make the socket inaccessible.
michael@0 337 dirName.permissions = allPermissions;
michael@0 338 socketName.permissions = 0;
michael@0 339
michael@0 340 let client2 = socketTransportService.createUnixDomainTransport(socketName);
michael@0 341 let client2AsyncInput = client2.openInputStream(0, 0, 0).QueryInterface(Ci.nsIAsyncInputStream);
michael@0 342 client2AsyncInput.asyncWait(function (aStream) {
michael@0 343 do_print("called test_connect_permission's client2's onInputStreamReady");
michael@0 344 log += '2';
michael@0 345
michael@0 346 do_check_throws_nsIException(() => client2AsyncInput.available(),
michael@0 347 "NS_ERROR_CONNECTION_REFUSED");
michael@0 348
michael@0 349 client2AsyncInput.close();
michael@0 350 client2.close(Cr.NS_OK);
michael@0 351
michael@0 352 // Now make everything accessible, and try one last time.
michael@0 353 socketName.permissions = allPermissions;
michael@0 354
michael@0 355 client3 = socketTransportService.createUnixDomainTransport(socketName);
michael@0 356
michael@0 357 let client3Output = client3.openOutputStream(0, 0, 0);
michael@0 358 client3Output.write("Hanratty", 8);
michael@0 359
michael@0 360 let client3AsyncInput = client3.openInputStream(0, 0, 0).QueryInterface(Ci.nsIAsyncInputStream);
michael@0 361 client3AsyncInput.asyncWait(client3InputStreamReady, 0, 0, threadManager.currentThread);
michael@0 362 }, 0, 0, threadManager.currentThread);
michael@0 363 }, 0, 0, threadManager.currentThread);
michael@0 364
michael@0 365 function socketAccepted(aServ, aTransport) {
michael@0 366 do_print("called test_connect_permission's onSocketAccepted");
michael@0 367 log += 'a';
michael@0 368
michael@0 369 let serverInput = aTransport.openInputStream(0, 0, 0).QueryInterface(Ci.nsIAsyncInputStream);
michael@0 370 let serverOutput = aTransport.openOutputStream(0, 0, 0);
michael@0 371
michael@0 372 serverInput.asyncWait(function (aStream) {
michael@0 373 do_print("called test_connect_permission's socketAccepted's onInputStreamReady");
michael@0 374 log += 'i';
michael@0 375
michael@0 376 // Receive data from the client, and send back a response.
michael@0 377 let serverScriptableInput = new ScriptableInputStream(serverInput);
michael@0 378 do_check_eq(serverScriptableInput.readBytes(8), "Hanratty");
michael@0 379 serverOutput.write("Ferlingatti", 11);
michael@0 380 }, 0, 0, threadManager.currentThread);
michael@0 381 }
michael@0 382
michael@0 383 function client3InputStreamReady(aStream) {
michael@0 384 do_print("called client3's onInputStreamReady");
michael@0 385 log += '3';
michael@0 386
michael@0 387 let client3Input = new ScriptableInputStream(aStream);
michael@0 388
michael@0 389 do_check_eq(client3Input.readBytes(11), "Ferlingatti");
michael@0 390
michael@0 391 client3.close(Cr.NS_OK);
michael@0 392 server.close();
michael@0 393 }
michael@0 394
michael@0 395 function stopListening(aServ, aStatus) {
michael@0 396 do_print("called test_connect_permission's server's stopListening");
michael@0 397 log += 's';
michael@0 398
michael@0 399 do_check_eq(log, '12ai3s');
michael@0 400
michael@0 401 run_next_test();
michael@0 402 }
michael@0 403 }
michael@0 404
michael@0 405 // Creating a socket with a long filename doesn't crash.
michael@0 406 function test_long_socket_name()
michael@0 407 {
michael@0 408 let socketName = do_get_tempdir();
michael@0 409 socketName.append(new Array(10000).join('long'));
michael@0 410
michael@0 411 // Try to create a server socket with the long name.
michael@0 412 do_check_throws_nsIException(() => new UnixServerSocket(socketName, allPermissions, -1),
michael@0 413 "NS_ERROR_FILE_NAME_TOO_LONG");
michael@0 414
michael@0 415 // Try to connect to a socket with the long name.
michael@0 416 do_check_throws_nsIException(() => socketTransportService.createUnixDomainTransport(socketName),
michael@0 417 "NS_ERROR_FILE_NAME_TOO_LONG");
michael@0 418
michael@0 419 run_next_test();
michael@0 420 }
michael@0 421
michael@0 422 // Going offline should not shut down Unix domain sockets.
michael@0 423 function test_keep_when_offline()
michael@0 424 {
michael@0 425 let log = '';
michael@0 426
michael@0 427 let socketName = do_get_tempdir();
michael@0 428 socketName.append('keep-when-offline');
michael@0 429
michael@0 430 // Create a listening socket.
michael@0 431 let listener = new UnixServerSocket(socketName, allPermissions, -1);
michael@0 432 listener.asyncListen({ onSocketAccepted: onAccepted, onStopListening: onStopListening });
michael@0 433
michael@0 434 // Connect a client socket to the listening socket.
michael@0 435 let client = socketTransportService.createUnixDomainTransport(socketName);
michael@0 436 let clientOutput = client.openOutputStream(0, 0, 0);
michael@0 437 let clientInput = client.openInputStream(0, 0, 0);
michael@0 438 clientInput.asyncWait(clientReady, 0, 0, threadManager.currentThread);
michael@0 439 let clientScriptableInput = new ScriptableInputStream(clientInput);
michael@0 440
michael@0 441 let server, serverInput, serverScriptableInput, serverOutput;
michael@0 442
michael@0 443 // How many times has the server invited the client to go first?
michael@0 444 let count = 0;
michael@0 445
michael@0 446 // The server accepted connection callback.
michael@0 447 function onAccepted(aListener, aServer) {
michael@0 448 do_print("test_keep_when_offline: onAccepted called");
michael@0 449 log += 'a';
michael@0 450 do_check_eq(aListener, listener);
michael@0 451 server = aServer;
michael@0 452
michael@0 453 // Prepare to receive messages from the client.
michael@0 454 serverInput = server.openInputStream(0, 0, 0);
michael@0 455 serverInput.asyncWait(serverReady, 0, 0, threadManager.currentThread);
michael@0 456 serverScriptableInput = new ScriptableInputStream(serverInput);
michael@0 457
michael@0 458 // Start a conversation with the client.
michael@0 459 serverOutput = server.openOutputStream(0, 0, 0);
michael@0 460 serverOutput.write("After you, Alphonse!", 20);
michael@0 461 count++;
michael@0 462 }
michael@0 463
michael@0 464 // The client has seen its end of the socket close.
michael@0 465 function clientReady(aStream) {
michael@0 466 log += 'c';
michael@0 467 do_print("test_keep_when_offline: clientReady called: " + log);
michael@0 468 do_check_eq(aStream, clientInput);
michael@0 469
michael@0 470 // If the connection has been closed, end the conversation and stop listening.
michael@0 471 let available;
michael@0 472 try {
michael@0 473 available = clientInput.available();
michael@0 474 } catch (ex) {
michael@0 475 do_check_instanceof(ex, Ci.nsIException);
michael@0 476 do_check_eq(ex.result, Cr.NS_BASE_STREAM_CLOSED);
michael@0 477
michael@0 478 do_print("client received end-of-stream; closing client output stream");
michael@0 479 log += ')';
michael@0 480
michael@0 481 client.close(Cr.NS_OK);
michael@0 482
michael@0 483 // Now both output streams have been closed, and both input streams
michael@0 484 // have received the close notification. Stop listening for
michael@0 485 // connections.
michael@0 486 listener.close();
michael@0 487 }
michael@0 488
michael@0 489 if (available) {
michael@0 490 // Check the message from the server.
michael@0 491 do_check_eq(clientScriptableInput.readBytes(20), "After you, Alphonse!");
michael@0 492
michael@0 493 // Write our response to the server.
michael@0 494 clientOutput.write("No, after you, Gaston!", 22);
michael@0 495
michael@0 496 // Ask to be called again, when more input arrives.
michael@0 497 clientInput.asyncWait(clientReady, 0, 0, threadManager.currentThread);
michael@0 498 }
michael@0 499 }
michael@0 500
michael@0 501 function serverReady(aStream) {
michael@0 502 log += 's';
michael@0 503 do_print("test_keep_when_offline: serverReady called: " + log);
michael@0 504 do_check_eq(aStream, serverInput);
michael@0 505
michael@0 506 // Check the message from the client.
michael@0 507 do_check_eq(serverScriptableInput.readBytes(22), "No, after you, Gaston!");
michael@0 508
michael@0 509 // This should not shut things down: Unix domain sockets should
michael@0 510 // remain open in offline mode.
michael@0 511 if (count == 5) {
michael@0 512 IOService.offline = true;
michael@0 513 log += 'o';
michael@0 514 }
michael@0 515
michael@0 516 if (count < 10) {
michael@0 517 // Insist.
michael@0 518 serverOutput.write("After you, Alphonse!", 20);
michael@0 519 count++;
michael@0 520
michael@0 521 // As long as the input stream is open, always ask to be called again
michael@0 522 // when more input arrives.
michael@0 523 serverInput.asyncWait(serverReady, 0, 0, threadManager.currentThread);
michael@0 524 } else if (count == 10) {
michael@0 525 // After sending ten times and receiving ten replies, we're not
michael@0 526 // going to send any more. Close the server's output stream; the
michael@0 527 // client's input stream should see this.
michael@0 528 do_print("closing server transport");
michael@0 529 server.close(Cr.NS_OK);
michael@0 530 log += '(';
michael@0 531 }
michael@0 532 }
michael@0 533
michael@0 534 // We have stopped listening.
michael@0 535 function onStopListening(aServ, aStatus) {
michael@0 536 do_print("test_keep_when_offline: onStopListening called");
michael@0 537 log += 'L';
michael@0 538 do_check_eq(log, 'acscscscscsocscscscscs(c)L');
michael@0 539
michael@0 540 do_check_eq(aServ, listener);
michael@0 541 do_check_eq(aStatus, Cr.NS_BINDING_ABORTED);
michael@0 542
michael@0 543 run_next_test();
michael@0 544 }
michael@0 545 }

mercurial