Chromium Code Reviews| Index: chrome/test/data/extensions/api_test/sockets_tcp/api/background.js |
| diff --git a/chrome/test/data/extensions/api_test/sockets_tcp/api/background.js b/chrome/test/data/extensions/api_test/sockets_tcp/api/background.js |
| index d5b4f12e027a371f8cfade90df7b7f83699a6fea..9f5d8f86ff94d5ab2b923e2e119fc23aed644f8b 100644 |
| --- a/chrome/test/data/extensions/api_test/sockets_tcp/api/background.js |
| +++ b/chrome/test/data/extensions/api_test/sockets_tcp/api/background.js |
| @@ -9,18 +9,27 @@ |
| // The response is based on the request but obfuscated using a random key. |
| const request = "0100000005320000005hello"; |
| var expectedResponsePattern = /0100000005320000005.{11}/; |
| +const http_get = "GET test.html HTTP/1.0\r\n\r\n"; |
| +var expectedHTTPPattern = /HTTP.1.0 200 OK/; |
| -var address; |
| +var tcp_address; |
| +var https_address; |
| var bytesSent = 0; |
| var dataAsString; |
| var dataRead = []; |
| -var port = -1; |
| +var tcp_port = -1; |
| +var https_port = -1; |
| var protocol = "none"; |
| -var socketId = 0; |
| +var tcp_socketId = 0; |
| +var https_socketId = 0; |
| var echoDataSent = false; |
| var succeeded = false; |
| var waitCount = 0; |
| +// Keys are socketIds. Values are inner dictionaries with two keys: onReceive, |
| +// onReceiveError. Both are functions. |
| +var receive_dispatcher = {} |
| + |
| // Many thanks to Dennis for his StackOverflow answer: http://goo.gl/UDanx |
| // Since amended to handle BlobBuilder deprecation. |
| function string2ArrayBuffer(string, callback) { |
| @@ -41,6 +50,25 @@ function arrayBuffer2String(buf, callback) { |
| f.readAsText(blob); |
| } |
| +function dispatchSocketReceive(receiveInfo) { |
| + if (receive_dispatcher[receiveInfo.socketId] !== undefined) { |
| + receive_dispatcher[receiveInfo.socketId].onReceive(receiveInfo); |
| + } else { |
| + console.log("dispatchSocketReceive: No handler for socket " + |
| + receiveInfo.socketId); |
| + } |
| +} |
| + |
| +function dispatchSocketReceiveError(receiveErrorInfo) { |
| + if (receive_dispatcher[receiveErrorInfo.socketId] !== undefined) { |
| + receive_dispatcher[receiveErrorInfo.socketId].onReceiveError( |
| + receiveErrorInfo); |
| + } else { |
| + console.log("dispatchSocketReceiveError: No handler for socket " + |
| + receiveErrorInfo.socketId); |
| + } |
| +} |
| + |
| var testSocketCreation = function() { |
| function onCreate(socketInfo) { |
| function onGetInfo(info) { |
| @@ -71,7 +99,6 @@ var testSocketCreation = function() { |
| chrome.sockets.tcp.create({}, onCreate); |
| }; |
| - |
| var testSending = function() { |
| dataRead = ""; |
| succeeded = false; |
| @@ -92,14 +119,16 @@ var testSending = function() { |
| function onCreateComplete(socketInfo) { |
| console.log("onCreateComplete"); |
| - socketId = socketInfo.socketId; |
| - chrome.test.assertTrue(socketId > 0, "failed to create socket"); |
| + tcp_socketId = socketInfo.socketId; |
| + chrome.test.assertTrue(tcp_socketId > 0, "failed to create socket"); |
| console.log("add event listeners"); |
| - chrome.sockets.tcp.onReceive.addListener(onSocketReceive); |
| - chrome.sockets.tcp.onReceiveError.addListener(onSocketReceiveError); |
| + receive_dispatcher[tcp_socketId] = { |
| + onReceive: onSocketReceive, |
| + onReceiveError: onSocketReceiveError |
| + }; |
| - chrome.sockets.tcp.getInfo(socketId, onGetInfoAfterCreateComplete); |
| + chrome.sockets.tcp.getInfo(tcp_socketId, onGetInfoAfterCreateComplete); |
| } |
| function onGetInfoAfterCreateComplete(result) { |
| @@ -120,7 +149,7 @@ var testSending = function() { |
| chrome.test.assertEq(104, result.bufferSize, "Buffer size did not persist"); |
| chrome.test.assertFalse(result.paused, "Socket should not be paused"); |
| - chrome.sockets.tcp.update(socketId, { |
| + chrome.sockets.tcp.update(tcp_socketId, { |
| "name": "test2", |
| "persistent": false, |
| bufferSize: 2048 |
| @@ -129,7 +158,7 @@ var testSending = function() { |
| function onUpdateComplete() { |
| console.log("onUpdateComplete"); |
| - chrome.sockets.tcp.getInfo(socketId, onGetInfoAfterUpdateComplete); |
| + chrome.sockets.tcp.getInfo(tcp_socketId, onGetInfoAfterUpdateComplete); |
| } |
| function onGetInfoAfterUpdateComplete(result) { |
| @@ -151,7 +180,8 @@ var testSending = function() { |
| "Buffer size did not persist"); |
| chrome.test.assertFalse(result.paused, "Socket should not be paused"); |
| - chrome.sockets.tcp.connect(socketId, address, port, onConnectComplete); |
| + chrome.sockets.tcp.connect(tcp_socketId, tcp_address, tcp_port, |
| + onConnectComplete); |
| } |
| function onConnectComplete(result) { |
| @@ -159,7 +189,7 @@ var testSending = function() { |
| chrome.test.assertEq(0, result, |
| "Connect failed with error " + result); |
| - chrome.sockets.tcp.getInfo(socketId, onGetInfoAfterConnectComplete); |
| + chrome.sockets.tcp.getInfo(tcp_socketId, onGetInfoAfterConnectComplete); |
| } |
| function onGetInfoAfterConnectComplete(result) { |
| @@ -173,33 +203,33 @@ var testSending = function() { |
| // IPs, not names. |
| chrome.test.assertEq(result.peerAddress, "127.0.0.1", |
| "Peer addresss should be the listen server"); |
| - chrome.test.assertEq(result.peerPort, port, |
| + chrome.test.assertEq(result.peerPort, tcp_port, |
| "Peer port should be the listen server"); |
| chrome.test.assertTrue(result.connected, "Socket should be connected"); |
| - chrome.sockets.tcp.setPaused(socketId, true, onSetPausedComplete); |
| + chrome.sockets.tcp.setPaused(tcp_socketId, true, onSetPausedComplete); |
| } |
| function onSetPausedComplete() { |
| console.log("onSetPausedComplete"); |
| - chrome.sockets.tcp.getInfo(socketId, onGetInfoAfterSetPausedComplete); |
| + chrome.sockets.tcp.getInfo(tcp_socketId, onGetInfoAfterSetPausedComplete); |
| } |
| function onGetInfoAfterSetPausedComplete(result) { |
| console.log("onGetInfoAfterSetPausedComplete"); |
| chrome.test.assertTrue(result.paused, "Socket should be paused"); |
| - chrome.sockets.tcp.setPaused(socketId, false, onUnpauseComplete); |
| + chrome.sockets.tcp.setPaused(tcp_socketId, false, onUnpauseComplete); |
| } |
| function onUnpauseComplete() { |
| console.log("onUnpauseComplete"); |
| - chrome.sockets.tcp.getInfo(socketId, onGetInfoAfterUnpauseComplete); |
| + chrome.sockets.tcp.getInfo(tcp_socketId, onGetInfoAfterUnpauseComplete); |
| } |
| function onGetInfoAfterUnpauseComplete(result) { |
| console.log("onGetInfoAfterUnpauseComplete"); |
| chrome.test.assertFalse(result.paused, "Socket should not be paused"); |
| - chrome.sockets.tcp.setNoDelay(socketId, true, onSetNoDelayComplete); |
| + chrome.sockets.tcp.setNoDelay(tcp_socketId, true, onSetNoDelayComplete); |
| } |
| function onSetNoDelayComplete(result) { |
| @@ -210,7 +240,7 @@ var testSending = function() { |
| "lastError=" + chrome.runtime.lastError.message); |
| } |
| chrome.sockets.tcp.setKeepAlive( |
| - socketId, true, 1000, onSetKeepAliveComplete); |
| + tcp_socketId, true, 1000, onSetKeepAliveComplete); |
| } |
| function onSetKeepAliveComplete(result) { |
| @@ -223,7 +253,7 @@ var testSending = function() { |
| string2ArrayBuffer(request, function(arrayBuffer) { |
| echoDataSent = true; |
| - chrome.sockets.tcp.send(socketId, arrayBuffer, onSendComplete); |
| + chrome.sockets.tcp.send(tcp_socketId, arrayBuffer, onSendComplete); |
| }); |
| } |
| @@ -237,13 +267,13 @@ var testSending = function() { |
| function onSocketReceive(receiveInfo) { |
| console.log("onSocketReceive"); |
| - chrome.test.assertEq(socketId, receiveInfo.socketId); |
| + chrome.test.assertEq(tcp_socketId, receiveInfo.socketId); |
| arrayBuffer2String(receiveInfo.data, function(s) { |
| dataAsString = s; // save this for error reporting |
| var match = !!s.match(expectedResponsePattern); |
| chrome.test.assertTrue(match, "Received data does not match."); |
| console.log("echo data received, closing socket"); |
| - chrome.sockets.tcp.close(socketId, onCloseComplete); |
| + chrome.sockets.tcp.close(tcp_socketId, onCloseComplete); |
| }); |
| } |
| @@ -268,6 +298,129 @@ var testSending = function() { |
| }; // testSending() |
| +var testSecure = function () { |
| + var request_sent = false; |
| + succeeded = false; |
| + dataAsString = ""; |
| + setTimeout(waitForBlockingOperation, 1000); |
| + |
| + // Run the test a few times. First with misuse_testing=MISUSE_NONE, |
| + // to test that the API works correctly when used properly. Then |
| + // with different values of misuse_mode, test that the API does |
| + // not malfunction when used improperly. Upon success, each misuse |
| + // must close the socket and call onCloseComplete(). |
| + var MISUSE_NONE = 0; |
| + var MISUSE_SECURE_PENDING_READ = 1; |
| + var MISUSE_LAST = MISUSE_SECURE_PENDING_READ; |
| + var misuse_mode = MISUSE_NONE; |
| + |
| + chrome.sockets.tcp.create({}, onCreateComplete); |
| + |
| + function onCreateComplete(socketInfo) { |
| + https_socketId = socketInfo.socketId; |
| + receive_dispatcher[https_socketId] = { |
| + onReceive: onSocketReceive, |
| + onReceiveError: onSocketReceiveError |
| + }; |
| + |
| + chrome.test.assertTrue(https_socketId > 0, "failed to create socket"); |
| + if (misuse_mode == MISUSE_SECURE_PENDING_READ) { |
| + // Don't pause the socket. This will let the sockets runtime |
| + // keep a pending read on it. |
| + console.log("HTTPS onCreateComplete: in MISUSE_SECURE_PENDING_READ " + |
| + "mode, skipping setPaused(false)."); |
| + onPausedComplete(); |
| + } else { |
| + chrome.sockets.tcp.setPaused(https_socketId, true, onPausedComplete); |
| + } |
| + } |
| + |
| + function onPausedComplete() { |
| + console.log("HTTPS onPausedComplete. Connecting to " +https_address + ":" + |
| + https_port); |
| + chrome.sockets.tcp.connect(https_socketId, https_address, https_port, |
| + onConnectComplete); |
| + } |
| + |
| + function onConnectComplete(result) { |
| + console.log("HTTPS onConnectComplete"); |
| + chrome.test.assertEq(0, result, |
| + "Connect failed with error " + result); |
| + chrome.sockets.tcp.secure(https_socketId, null, onSecureComplete); |
| + } |
| + |
| + function onSecureComplete(result) { |
| + console.log("HTTPS onSecureComplete(" + result + ")"); |
| + if (misuse_mode == MISUSE_SECURE_PENDING_READ) { |
| + // net::ERR_INVALID_ARGUMENT is -4. |
|
Ryan Sleevi
2014/03/26 19:57:40
Wait, are we surfing the net:: errors as part of t
lally
2014/03/28 16:22:51
Ah, I didn't think that this was a declaration of
|
| + chrome.test.assertEq(-4, result, |
| + "Secure should have failed when a read " + |
| + "was pending (" + result + ")"); |
| + chrome.sockets.tcp.close(https_socketId, onCloseComplete); |
| + } else { |
| + chrome.test.assertEq(0, result, |
| + "Secure failed with error " + result); |
| + chrome.sockets.tcp.setPaused(https_socketId, false, onUnpauseComplete); |
| + } |
| + } |
| + |
| + function onUnpauseComplete() { |
| + console.log("HTTPS onUnpauseComplete"); |
| + string2ArrayBuffer(http_get, function(arrayBuffer) { |
| + request_sent = true; |
| + chrome.sockets.tcp.send(https_socketId, arrayBuffer, onSendComplete); |
| + }); |
| + } |
| + |
| + function onSendComplete(sendInfo) { |
| + console.log("HTTPS onSendComplete: " + sendInfo.bytesSent + " bytes."); |
| + chrome.test.assertEq(0, sendInfo.resultCode, "Send failed."); |
| + chrome.test.assertTrue(sendInfo.bytesSent > 0, |
| + "Send didn't write bytes."); |
| + bytesSent += sendInfo.bytesSent; |
| + } |
| + |
| + function onSocketReceive(receiveInfo) { |
| + console.log("HTTPS onSocketReceive"); |
| + chrome.test.assertEq(https_socketId, receiveInfo.socketId); |
| + arrayBuffer2String(receiveInfo.data, function(s) { |
| + // we will get more data than we care about. We only care about the |
| + // first segment of data (the HTTP 200 code). Ignore the rest, which |
| + // won't match the pattern. |
| + if (succeeded == false) { |
| + dataAsString = s; // for waitForBlockingOperation(). |
| + console.log("HTTPS receive: got " + s); |
| + var match = !!s.match(expectedHTTPPattern); |
| + chrome.test.assertTrue(match, "Received data does not match."); |
| + console.log("HTTPS response received, closing socket."); |
| + chrome.sockets.tcp.close(https_socketId, onCloseComplete); |
| + } |
| + succeeded = true; |
| + }); |
| + } |
| + |
| + function onSocketReceiveError(receiveErrorInfo) { |
| + console.log("HTTPS onSocketReceiveError"); |
| + if (request_sent) { |
| + return; |
| + } |
| + chrome.test.fail("Receive error on socket " + receiveErrorInfo.socketId + |
| + ": result code=" + receiveErrorInfo.resultCode); |
| + } |
| + |
| + function onCloseComplete() { |
| + console.log("HTTPS Test Succeeded"); |
| + if (misuse_mode == MISUSE_LAST) { |
| + // The test has run in all misuse modes. |
| + chrome.test.succeed(); |
| + } else { |
| + // Run the test again in the next misuse mode. |
| + misuse_mode += 1; |
| + chrome.sockets.tcp.create({}, onCreateComplete); |
| + } |
| + } |
| +}; // testSecure() |
| + |
| function waitForBlockingOperation() { |
| if (++waitCount < 10) { |
| setTimeout(waitForBlockingOperation, 1000); |
| @@ -279,18 +432,32 @@ function waitForBlockingOperation() { |
| } |
| var onMessageReply = function(message) { |
| - var parts = message.split(":"); |
| - var test_type = parts[0]; |
| - address = parts[1]; |
| - port = parseInt(parts[2]); |
| - console.log("Running tests, protocol " + test_type + ", echo server " + |
| - address + ":" + port); |
| - if (test_type == 'tcp') { |
| - protocol = test_type; |
| - chrome.test.runTests([testSocketCreation, testSending]); |
| - } else { |
| - chrome.test.fail("Invalid test type: " + test_type); |
| + var components = message.split(','); |
| + var tests = []; |
| + for (var i = 0; i < components.length; ++i) { |
| + var parts = components[i].split(":"); |
| + var test_type = parts[0]; |
| + if (test_type == 'tcp') { |
| + tcp_address = parts[1]; |
| + tcp_port = parseInt(parts[2]); |
| + console.log("Running tests for TCP, echo server " + |
| + tcp_address + ":" + tcp_port); |
| + tests = tests.concat([testSocketCreation, testSending]); |
| + } else if (test_type == 'https') { |
| + https_address = parts[1]; |
| + https_port = parseInt(parts[2]); |
| + console.log("Running tests for HTTPS, server " + |
| + https_address + ":" + https_port); |
| + tests = tests.concat([testSecure]); |
| + } else { |
| + chrome.test.fail("Invalid test type: " + test_type); |
| + } |
| } |
| + // Setup the suite-wide event listeners. |
| + chrome.sockets.tcp.onReceive.addListener(dispatchSocketReceive); |
| + chrome.sockets.tcp.onReceiveError.addListener(dispatchSocketReceiveError); |
| + |
| + chrome.test.runTests(tests); |
| }; |
| // Find out which protocol we're supposed to test, and which echo server we |