Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(102)

Unified Diff: extensions/test/data/serial_unittest.js

Issue 509813002: Implement the client side of Serial I/O on data pipe. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@serial-io
Patch Set: remove TimeoutManager.pause() Created 6 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: extensions/test/data/serial_unittest.js
diff --git a/extensions/test/data/serial_unittest.js b/extensions/test/data/serial_unittest.js
index dc7bbea56e06cddd8453f3a73358d177fe90f9fb..c3cc504bd6132814736930a0a11e7a92b1a0c185 100644
--- a/extensions/test/data/serial_unittest.js
+++ b/extensions/test/data/serial_unittest.js
@@ -6,29 +6,69 @@
* Unit tests for the JS serial service client.
*
* These test that configuration and data are correctly transmitted between the
- * client and the service.
+ * client and the service. They are launched by
+ * extensions/renderer/api/serial/serial_api_unittest.cc.
*/
var test = require('test').binding;
var serial = require('serial').binding;
var unittestBindings = require('test_environment_specific_bindings');
+var utils = require('utils');
+
+var timeoutManager = new unittestBindings.TimeoutManager();
+timeoutManager.installGlobals();
+
+var BUFFER_SIZE = 10;
var connectionId = null;
function connect(callback, options) {
options = options || {
name: 'test connection',
- bufferSize: 8192,
+ bufferSize: BUFFER_SIZE,
receiveTimeout: 12345,
sendTimeout: 6789,
persistent: true,
- }
+ };
serial.connect('device', options, test.callbackPass(function(connectionInfo) {
connectionId = connectionInfo.connectionId;
- callback(connectionInfo);
+ if (callback)
+ callback(connectionInfo);
}));
}
+// Sets a function to be called once when data is received. Returns a promise
+// that will resolve once the hook is installed.
+function addReceiveHook(callback) {
+ return requireAsync('serial_service').then(function(serialService) {
+ var called = false;
+ var dataReceived = serialService.Connection.prototype.onDataReceived_;
+ serialService.Connection.prototype.onDataReceived_ = function() {
+ var result = $Function.apply(dataReceived, this, arguments);
+ if (!called)
+ callback();
+ called = true;
+ return result;
+ };
+ });
+}
+
+// Sets a function to be called once when a receive error is received. Returns a
+// promise that will resolve once the hook is installed.
+function addReceiveErrorHook(callback) {
+ return requireAsync('serial_service').then(function(serialService) {
+ var called = false;
+ var receiveError = serialService.Connection.prototype.onReceiveError_;
+ serialService.Connection.prototype.onReceiveError_ = function() {
+ var result = $Function.apply(receiveError, this, arguments);
+ if (!called)
+ callback();
+ called = true;
+ return result;
+ };
+ });
+}
+
function disconnect() {
serial.disconnect(connectionId, test.callbackPass(function(success) {
test.assertTrue(success);
@@ -41,7 +81,7 @@ function checkClientConnectionInfo(connectionInfo) {
test.assertEq('test connection', connectionInfo.name);
test.assertEq(12345, connectionInfo.receiveTimeout);
test.assertEq(6789, connectionInfo.sendTimeout);
- test.assertEq(8192, connectionInfo.bufferSize);
+ test.assertEq(BUFFER_SIZE, connectionInfo.bufferSize);
test.assertFalse(connectionInfo.paused);
}
@@ -58,7 +98,52 @@ function checkConnectionInfo(connectionInfo) {
checkServiceConnectionInfo(connectionInfo);
}
+function runReceiveErrorTest(expectedError) {
+ connect();
+ test.listenOnce(serial.onReceiveError, function(result) {
+ serial.getInfo(connectionId, test.callbackPass(function(connectionInfo) {
+ disconnect();
+ test.assertTrue(connectionInfo.paused);
+ }));
+ test.assertEq(connectionId, result.connectionId);
+ test.assertEq(expectedError, result.error);
+ });
+}
+
+function runSendErrorTest(expectedError) {
+ connect(function() {
+ var buffer = new ArrayBuffer(1);
+ serial.send(connectionId, buffer, test.callbackPass(function(sendInfo) {
+ disconnect();
+ test.assertEq(0, sendInfo.bytesSent);
+ test.assertEq(expectedError, sendInfo.error);
+ }));
+ });
+}
+
+function sendData() {
+ var data = 'data';
+ var buffer = new ArrayBuffer(data.length);
+ var byteBuffer = new Int8Array(buffer);
+ for (var i = 0; i < data.length; i++) {
+ byteBuffer[i] = data.charCodeAt(i);
+ }
+ return utils.promise(serial.send, connectionId, buffer);
+}
+
+function checkReceivedData(result) {
+ var data = 'data';
+ test.assertEq(connectionId, result.connectionId);
+ test.assertEq(data.length, result.data.byteLength);
+ var resultByteBuffer = new Int8Array(result.data);
+ for (var i = 0; i < data.length; i++) {
+ test.assertEq(data.charCodeAt(i), resultByteBuffer[i]);
+ }
+}
+
unittestBindings.exportTests([
+ // Test that getDevices correctly transforms the data returned by the
+ // SerialDeviceEnumerator.
function testGetDevices() {
serial.getDevices(test.callbackPass(function(devices) {
test.assertEq(3, devices.length);
@@ -74,21 +159,29 @@ unittestBindings.exportTests([
}));
},
+ // Test that the correct error message is returned when an error occurs in
+ // connecting to the port. This test uses an IoHandler that fails to connect.
function testConnectFail() {
serial.connect('device',
test.callbackFail('Failed to connect to the port.'));
},
+ // Test that the correct error message is returned when an error occurs in
+ // calling getPortInfo after connecting to the port. This test uses an
+ // IoHandler that fails on calls to GetPortInfo.
function testGetInfoFailOnConnect() {
serial.connect('device',
test.callbackFail('Failed to connect to the port.'));
},
+ // Test that the correct error message is returned when an invalid bit-rate
+ // value is passed to connect.
function testConnectInvalidBitrate() {
serial.connect('device', {bitrate: -1}, test.callbackFail(
'Failed to connect to the port.'));
},
+ // Test that a successful connect returns the expected connection info.
function testConnect() {
connect(function(connectionInfo) {
disconnect();
@@ -96,6 +189,8 @@ unittestBindings.exportTests([
});
},
+ // Test that a connection created with no options has the correct default
+ // options.
function testConnectDefaultOptions() {
connect(function(connectionInfo) {
disconnect();
@@ -112,6 +207,8 @@ unittestBindings.exportTests([
}, {});
},
+ // Test that a getInfo call correctly converts the service-side info from the
+ // Mojo format and returns both it and the client-side configuration.
function testGetInfo() {
connect(function() {
serial.getInfo(connectionId,
@@ -122,6 +219,9 @@ unittestBindings.exportTests([
});
},
+ // Test that only client-side options are returned when the service fails a
+ // getInfo call. This test uses an IoHandler that fails GetPortInfo calls
+ // after the initial call during connect.
function testGetInfoFailToGetPortInfo() {
connect(function() {
serial.getInfo(connectionId,
@@ -137,6 +237,7 @@ unittestBindings.exportTests([
});
},
+ // Test that getConnections returns an array containing the open connection.
function testGetConnections() {
connect(function() {
serial.getConnections(test.callbackPass(function(connections) {
@@ -147,6 +248,9 @@ unittestBindings.exportTests([
});
},
+ // Test that getControlSignals correctly converts the Mojo format result. This
+ // test uses an IoHandler that returns values matching the pattern being
+ // tested.
function testGetControlSignals() {
connect(function() {
var calls = 0;
@@ -169,6 +273,9 @@ unittestBindings.exportTests([
});
},
+ // Test that setControlSignals correctly converts to the Mojo format result.
+ // This test uses an IoHandler that returns values following the same table of
+ // values as |signalsValues|.
function testSetControlSignals() {
connect(function() {
var signalsValues = [
@@ -197,6 +304,10 @@ unittestBindings.exportTests([
});
},
+ // Test that update correctly passes values to the service only for
+ // service-side options and that all update calls are reflected by the result
+ // of getInfo calls. This test uses an IoHandler that expects corresponding
+ // ConfigurePort calls.
function testUpdate() {
connect(function() {
var optionsValues = [
@@ -240,6 +351,7 @@ unittestBindings.exportTests([
});
},
+ // Test that passing an invalid bit-rate reslts in an error.
function testUpdateInvalidBitrate() {
connect(function() {
serial.update(connectionId,
@@ -251,16 +363,19 @@ unittestBindings.exportTests([
});
},
+ // Test flush. This test uses an IoHandler that counts the number of flush
+ // calls.
function testFlush() {
connect(function() {
- serial.flush(connectionId,
- test.callbackPass(function(success) {
+ serial.flush(connectionId, test.callbackPass(function(success) {
disconnect();
test.assertTrue(success);
}));
});
},
+ // Test that setPaused values are reflected by the results returned by getInfo
+ // calls.
function testSetPaused() {
connect(function() {
serial.setPaused(connectionId, true, test.callbackPass(function() {
@@ -277,36 +392,283 @@ unittestBindings.exportTests([
});
},
+ // Test that a send and a receive correctly echoes data. This uses an
+ // IoHandler that echoes data sent to it.
+ function testEcho() {
+ connect(function() {
+ sendData().then(test.callbackPass(function(sendInfo) {
+ test.assertEq(4, sendInfo.bytesSent);
+ test.assertEq(undefined, sendInfo.error);
+ }));
+ test.listenOnce(serial.onReceive, function(result) {
+ checkReceivedData(result);
+ disconnect();
+ });
+ });
+ },
+
+ // Test that a send while another send is in progress returns a pending error.
+ function testSendDuringExistingSend() {
+ connect(function() {
+ sendData().then(test.callbackPass(function(sendInfo) {
+ test.assertEq(4, sendInfo.bytesSent);
+ test.assertEq(undefined, sendInfo.error);
+ disconnect();
+ }));
+ sendData().then(test.callbackPass(function(sendInfo) {
+ test.assertEq(0, sendInfo.bytesSent);
+ test.assertEq('pending', sendInfo.error);
+ }));
+ });
+ },
+
+ // Test that a second send after the first finishes is successful. This uses
+ // an IoHandler that echoes data sent to it.
+ function testSendAfterSuccessfulSend() {
+ connect(function() {
+ sendData().then(test.callbackPass(function(sendInfo) {
+ test.assertEq(4, sendInfo.bytesSent);
+ test.assertEq(undefined, sendInfo.error);
+ return sendData();
+ })).then(test.callbackPass(function(sendInfo) {
+ test.assertEq(4, sendInfo.bytesSent);
+ test.assertEq(undefined, sendInfo.error);
+ }));
+ // Check that the correct data is echoed twice.
+ test.listenOnce(serial.onReceive, function(result) {
+ checkReceivedData(result);
+ test.listenOnce(serial.onReceive, function(result) {
+ checkReceivedData(result);
+ disconnect();
+ });
+ });
+ });
+ },
+
+ // Test that a second send after the first fails is successful. This uses an
+ // IoHandler that returns system_error for only the first send.
+ function testSendPartialSuccessWithError() {
+ connect(function() {
+ sendData().then(test.callbackPass(function(sendInfo) {
+ test.assertEq(2, sendInfo.bytesSent);
+ test.assertEq('system_error', sendInfo.error);
+ return sendData();
+ })).then(test.callbackPass(function(sendInfo) {
+ test.assertEq(4, sendInfo.bytesSent);
+ test.assertEq(undefined, sendInfo.error);
+ disconnect();
+ }));
+ });
+ },
+
+ // Test that a timed-out send returns a timeout error and that changing the
+ // send timeout during a send does not affect its timeout. This test uses an
+ // IoHandle that never completes sends.
+ function testSendTimeout() {
+ connect(function() {
+ sendData().then(test.callbackPass(function(sendInfo) {
+ test.assertEq(0, sendInfo.bytesSent);
+ test.assertEq('timeout', sendInfo.error);
+ test.assertEq(5, timeoutManager.currentTime);
+ disconnect();
+ }));
+ serial.update(connectionId, {sendTimeout: 10}, test.callbackPass(
+ timeoutManager.run.bind(timeoutManager, 1)));
+ }, {sendTimeout: 5});
+ },
+
+ // Test that a timed-out send returns a timeout error and that disabling the
+ // send timeout during a send does not affect its timeout. This test uses an
+ // IoHandle that never completes sends.
+ function testDisableSendTimeout() {
+ connect(function() {
+ sendData().then(test.callbackPass(function(sendInfo) {
+ test.assertEq(0, sendInfo.bytesSent);
+ test.assertEq('timeout', sendInfo.error);
+ test.assertEq(6, timeoutManager.currentTime);
+ disconnect();
+ }));
+ serial.update(connectionId, {sendTimeout: 0}, test.callbackPass(
+ timeoutManager.run.bind(timeoutManager, 1)));
+ }, {sendTimeout: 6});
+ },
+
+ // Test that data received while the connection is paused is queued and
+ // dispatched once the connection is unpaused.
+ function testPausedReceive() {
+ // Wait until the receive hook is installed, then start the test.
+ addReceiveHook(function() {
+ // Unpause the connection after the connection has queued the received
+ // data to ensure the queued data is dispatched when the connection is
+ // unpaused.
+ serial.setPaused(connectionId, false, test.callbackPass());
+ // Check that setPaused(false) is idempotent.
+ serial.setPaused(connectionId, false, test.callbackPass());
+ }).then(function() {
+ connect(function() {
+ // Check that setPaused(true) is idempotent.
+ serial.setPaused(connectionId, true, test.callbackPass());
+ serial.setPaused(connectionId, true, test.callbackPass());
+ });
+ });
+ test.listenOnce(serial.onReceive, function(result) {
+ checkReceivedData(result);
+ disconnect();
+ });
+ },
+
+ // Test that a receive error received while the connection is paused is queued
+ // and dispatched once the connection is unpaused.
+ function testPausedReceiveError() {
+ addReceiveErrorHook(function() {
+ // Unpause the connection after the connection has queued the receive
+ // error to ensure the queued error is dispatched when the connection is
+ // unpaused.
+ serial.setPaused(connectionId, false, test.callbackPass());
+ }).then(test.callbackPass(function() {
+ connect(function() {
+ serial.setPaused(connectionId, true, test.callbackPass());
+ });
+ }));
+
+ test.listenOnce(serial.onReceiveError, function(result) {
+ serial.getInfo(connectionId, test.callbackPass(function(connectionInfo) {
+ disconnect();
+ test.assertTrue(connectionInfo.paused);
+ }));
+ test.assertEq(connectionId, result.connectionId);
+ test.assertEq('device_lost', result.error);
+ });
+ serial.onReceive.addListener(function() {
+ test.fail('unexpected onReceive event');
+ });
+ },
+
+ // Test that receive timeouts trigger after the timeout time elapses and that
+ // changing the receive timeout does not affect a wait in progress.
+ function testReceiveTimeout() {
+ connect(function() {
+ test.listenOnce(serial.onReceiveError, function(result) {
+ test.assertEq(connectionId, result.connectionId);
+ test.assertEq('timeout', result.error);
+ test.assertEq(20, timeoutManager.currentTime);
+ serial.getInfo(connectionId, test.callbackPass(
+ function(connectionInfo) {
+ test.assertFalse(connectionInfo.paused);
+ disconnect();
+ }));
+ });
+ // Changing the timeout does not take effect until the current timeout
+ // expires or a receive completes.
+ serial.update(connectionId, {receiveTimeout: 10}, test.callbackPass(
+ timeoutManager.run.bind(timeoutManager, 1)));
+ }, {receiveTimeout: 20});
+ },
+
+ // Test that receive timeouts trigger after the timeout time elapses and that
+ // disabling the receive timeout does not affect a wait in progress.
+ function testDisableReceiveTimeout() {
+ connect(function() {
+ test.listenOnce(serial.onReceiveError, function(result) {
+ test.assertEq(connectionId, result.connectionId);
+ test.assertEq('timeout', result.error);
+ test.assertEq(30, timeoutManager.currentTime);
+ serial.getInfo(connectionId, test.callbackPass(
+ function(connectionInfo) {
+ disconnect();
+ test.assertFalse(connectionInfo.paused);
+ }));
+ });
+ // Disabling the timeout does not take effect until the current timeout
+ // expires or a receive completes.
+ serial.update(connectionId, {receiveTimeout: 0}, test.callbackPass(
+ timeoutManager.run.bind(timeoutManager, 1)));
+ }, {receiveTimeout: 30});
+ },
+
+ // Test that a receive error from the service is correctly dispatched. This
+ // test uses an IoHandler that only reports 'disconnected' receive errors.
+ function testReceiveErrorDisconnected() {
+ runReceiveErrorTest('disconnected');
+ },
+
+ // Test that a receive error from the service is correctly dispatched. This
+ // test uses an IoHandler that only reports 'device_lost' receive errors.
+ function testReceiveErrorDeviceLost() {
+ runReceiveErrorTest('device_lost');
+ },
+
+ // Test that a receive from error the service is correctly dispatched. This
+ // test uses an IoHandler that only reports 'system_error' receive errors.
+ function testReceiveErrorSystemError() {
+ runReceiveErrorTest('system_error');
+ },
+
+ // Test that a send error from the service is correctly returned as the send
+ // result. This test uses an IoHandler that only reports 'disconnected' send
+ // errors.
+ function testSendErrorDisconnected() {
+ runSendErrorTest('disconnected');
+ },
+
+ // Test that a send error from the service is correctly returned as the send
+ // result. This test uses an IoHandler that only reports 'system_error' send
+ // errors.
+ function testSendErrorSystemError() {
+ runSendErrorTest('system_error');
+ },
+
+ // Test that disconnect returns the correct error for a connection ID that
+ // does not exist.
function testDisconnectUnknownConnectionId() {
serial.disconnect(-1, test.callbackFail('Serial connection not found.'));
},
+ // Test that getInfo returns the correct error for a connection ID that does
+ // not exist.
function testGetInfoUnknownConnectionId() {
serial.getInfo(-1, test.callbackFail('Serial connection not found.'));
},
+ // Test that update returns the correct error for a connection ID that does
+ // not exist.
function testUpdateUnknownConnectionId() {
serial.update(-1, {}, test.callbackFail('Serial connection not found.'));
},
+ // Test that setControlSignals returns the correct error for a connection ID
+ // that does not exist.
function testSetControlSignalsUnknownConnectionId() {
serial.setControlSignals(-1, {}, test.callbackFail(
'Serial connection not found.'));
},
+ // Test that getControlSignals returns the correct error for a connection ID
+ // that does not exist.
function testGetControlSignalsUnknownConnectionId() {
serial.getControlSignals(-1, test.callbackFail(
'Serial connection not found.'));
},
+ // Test that flush returns the correct error for a connection ID that does not
+ // exist.
function testFlushUnknownConnectionId() {
serial.flush(-1, test.callbackFail('Serial connection not found.'));
},
+ // Test that setPaused returns the correct error for a connection ID that does
+ // not exist.
function testSetPausedUnknownConnectionId() {
serial.setPaused(
-1, true, test.callbackFail('Serial connection not found.'));
serial.setPaused(
-1, false, test.callbackFail('Serial connection not found.'));
},
+
+ // Test that send returns the correct error for a connection ID that does not
+ // exist.
+ function testSendUnknownConnectionId() {
+ var buffer = new ArrayBuffer(1);
+ serial.send(-1, buffer, test.callbackFail('Serial connection not found.'));
+ },
], test.runTests, exports);
« no previous file with comments | « extensions/renderer/resources/serial_service.js ('k') | extensions/test/data/unit_test_environment_specific_bindings.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698