OLD | NEW |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 /** | 5 /** |
6 * Unit tests for the JS serial service client. | 6 * Unit tests for the JS serial service client. |
7 * | 7 * |
8 * These test that configuration and data are correctly transmitted between the | 8 * These test that configuration and data are correctly transmitted between the |
9 * client and the service. | 9 * client and the service. They are launched by |
| 10 * extensions/renderer/api/serial/serial_api_unittest.cc. |
10 */ | 11 */ |
11 | 12 |
12 var test = require('test').binding; | 13 var test = require('test').binding; |
13 var serial = require('serial').binding; | 14 var serial = require('serial').binding; |
14 var unittestBindings = require('test_environment_specific_bindings'); | 15 var unittestBindings = require('test_environment_specific_bindings'); |
| 16 var utils = require('utils'); |
| 17 |
| 18 var timeoutManager = new unittestBindings.TimeoutManager(); |
| 19 timeoutManager.installGlobals(); |
| 20 |
| 21 var BUFFER_SIZE = 10; |
15 | 22 |
16 var connectionId = null; | 23 var connectionId = null; |
17 | 24 |
18 function connect(callback, options) { | 25 function connect(callback, options) { |
19 options = options || { | 26 options = options || { |
20 name: 'test connection', | 27 name: 'test connection', |
21 bufferSize: 8192, | 28 bufferSize: BUFFER_SIZE, |
22 receiveTimeout: 12345, | 29 receiveTimeout: 12345, |
23 sendTimeout: 6789, | 30 sendTimeout: 6789, |
24 persistent: true, | 31 persistent: true, |
25 } | 32 }; |
26 serial.connect('device', options, test.callbackPass(function(connectionInfo) { | 33 serial.connect('device', options, test.callbackPass(function(connectionInfo) { |
27 connectionId = connectionInfo.connectionId; | 34 connectionId = connectionInfo.connectionId; |
28 callback(connectionInfo); | 35 if (callback) |
| 36 callback(connectionInfo); |
29 })); | 37 })); |
30 } | 38 } |
31 | 39 |
| 40 // Sets a function to be called once when data is received. Returns a promise |
| 41 // that will resolve once the hook is installed. |
| 42 function addReceiveHook(callback) { |
| 43 return requireAsync('serial_service').then(function(serialService) { |
| 44 var called = false; |
| 45 var dataReceived = serialService.Connection.prototype.onDataReceived_; |
| 46 serialService.Connection.prototype.onDataReceived_ = function() { |
| 47 var result = $Function.apply(dataReceived, this, arguments); |
| 48 if (!called) |
| 49 callback(); |
| 50 called = true; |
| 51 return result; |
| 52 }; |
| 53 }); |
| 54 } |
| 55 |
| 56 // Sets a function to be called once when a receive error is received. Returns a |
| 57 // promise that will resolve once the hook is installed. |
| 58 function addReceiveErrorHook(callback) { |
| 59 return requireAsync('serial_service').then(function(serialService) { |
| 60 var called = false; |
| 61 var receiveError = serialService.Connection.prototype.onReceiveError_; |
| 62 serialService.Connection.prototype.onReceiveError_ = function() { |
| 63 var result = $Function.apply(receiveError, this, arguments); |
| 64 if (!called) |
| 65 callback(); |
| 66 called = true; |
| 67 return result; |
| 68 }; |
| 69 }); |
| 70 } |
| 71 |
32 function disconnect() { | 72 function disconnect() { |
33 serial.disconnect(connectionId, test.callbackPass(function(success) { | 73 serial.disconnect(connectionId, test.callbackPass(function(success) { |
34 test.assertTrue(success); | 74 test.assertTrue(success); |
35 connectionId = null; | 75 connectionId = null; |
36 })); | 76 })); |
37 } | 77 } |
38 | 78 |
39 function checkClientConnectionInfo(connectionInfo) { | 79 function checkClientConnectionInfo(connectionInfo) { |
40 test.assertFalse(connectionInfo.persistent); | 80 test.assertFalse(connectionInfo.persistent); |
41 test.assertEq('test connection', connectionInfo.name); | 81 test.assertEq('test connection', connectionInfo.name); |
42 test.assertEq(12345, connectionInfo.receiveTimeout); | 82 test.assertEq(12345, connectionInfo.receiveTimeout); |
43 test.assertEq(6789, connectionInfo.sendTimeout); | 83 test.assertEq(6789, connectionInfo.sendTimeout); |
44 test.assertEq(8192, connectionInfo.bufferSize); | 84 test.assertEq(BUFFER_SIZE, connectionInfo.bufferSize); |
45 test.assertFalse(connectionInfo.paused); | 85 test.assertFalse(connectionInfo.paused); |
46 } | 86 } |
47 | 87 |
48 function checkServiceConnectionInfo(connectionInfo) { | 88 function checkServiceConnectionInfo(connectionInfo) { |
49 test.assertEq(9600, connectionInfo.bitrate); | 89 test.assertEq(9600, connectionInfo.bitrate); |
50 test.assertEq('eight', connectionInfo.dataBits); | 90 test.assertEq('eight', connectionInfo.dataBits); |
51 test.assertEq('no', connectionInfo.parityBit); | 91 test.assertEq('no', connectionInfo.parityBit); |
52 test.assertEq('one', connectionInfo.stopBits); | 92 test.assertEq('one', connectionInfo.stopBits); |
53 test.assertFalse(connectionInfo.ctsFlowControl); | 93 test.assertFalse(connectionInfo.ctsFlowControl); |
54 } | 94 } |
55 | 95 |
56 function checkConnectionInfo(connectionInfo) { | 96 function checkConnectionInfo(connectionInfo) { |
57 checkClientConnectionInfo(connectionInfo); | 97 checkClientConnectionInfo(connectionInfo); |
58 checkServiceConnectionInfo(connectionInfo); | 98 checkServiceConnectionInfo(connectionInfo); |
59 } | 99 } |
60 | 100 |
| 101 function runReceiveErrorTest(expectedError) { |
| 102 connect(); |
| 103 test.listenOnce(serial.onReceiveError, function(result) { |
| 104 serial.getInfo(connectionId, test.callbackPass(function(connectionInfo) { |
| 105 disconnect(); |
| 106 test.assertTrue(connectionInfo.paused); |
| 107 })); |
| 108 test.assertEq(connectionId, result.connectionId); |
| 109 test.assertEq(expectedError, result.error); |
| 110 }); |
| 111 } |
| 112 |
| 113 function runSendErrorTest(expectedError) { |
| 114 connect(function() { |
| 115 var buffer = new ArrayBuffer(1); |
| 116 serial.send(connectionId, buffer, test.callbackPass(function(sendInfo) { |
| 117 disconnect(); |
| 118 test.assertEq(0, sendInfo.bytesSent); |
| 119 test.assertEq(expectedError, sendInfo.error); |
| 120 })); |
| 121 }); |
| 122 } |
| 123 |
| 124 function sendData() { |
| 125 var data = 'data'; |
| 126 var buffer = new ArrayBuffer(data.length); |
| 127 var byteBuffer = new Int8Array(buffer); |
| 128 for (var i = 0; i < data.length; i++) { |
| 129 byteBuffer[i] = data.charCodeAt(i); |
| 130 } |
| 131 return utils.promise(serial.send, connectionId, buffer); |
| 132 } |
| 133 |
| 134 function checkReceivedData(result) { |
| 135 var data = 'data'; |
| 136 test.assertEq(connectionId, result.connectionId); |
| 137 test.assertEq(data.length, result.data.byteLength); |
| 138 var resultByteBuffer = new Int8Array(result.data); |
| 139 for (var i = 0; i < data.length; i++) { |
| 140 test.assertEq(data.charCodeAt(i), resultByteBuffer[i]); |
| 141 } |
| 142 } |
| 143 |
61 unittestBindings.exportTests([ | 144 unittestBindings.exportTests([ |
| 145 // Test that getDevices correctly transforms the data returned by the |
| 146 // SerialDeviceEnumerator. |
62 function testGetDevices() { | 147 function testGetDevices() { |
63 serial.getDevices(test.callbackPass(function(devices) { | 148 serial.getDevices(test.callbackPass(function(devices) { |
64 test.assertEq(3, devices.length); | 149 test.assertEq(3, devices.length); |
65 test.assertEq(4, $Object.keys(devices[0]).length); | 150 test.assertEq(4, $Object.keys(devices[0]).length); |
66 test.assertEq('device', devices[0].path); | 151 test.assertEq('device', devices[0].path); |
67 test.assertEq(1234, devices[0].vendorId); | 152 test.assertEq(1234, devices[0].vendorId); |
68 test.assertEq(5678, devices[0].productId); | 153 test.assertEq(5678, devices[0].productId); |
69 test.assertEq('foo', devices[0].displayName); | 154 test.assertEq('foo', devices[0].displayName); |
70 test.assertEq(1, $Object.keys(devices[1]).length); | 155 test.assertEq(1, $Object.keys(devices[1]).length); |
71 test.assertEq('another_device', devices[1].path); | 156 test.assertEq('another_device', devices[1].path); |
72 test.assertEq(1, $Object.keys(devices[2]).length); | 157 test.assertEq(1, $Object.keys(devices[2]).length); |
73 test.assertEq('', devices[2].path); | 158 test.assertEq('', devices[2].path); |
74 })); | 159 })); |
75 }, | 160 }, |
76 | 161 |
| 162 // Test that the correct error message is returned when an error occurs in |
| 163 // connecting to the port. This test uses an IoHandler that fails to connect. |
77 function testConnectFail() { | 164 function testConnectFail() { |
78 serial.connect('device', | 165 serial.connect('device', |
79 test.callbackFail('Failed to connect to the port.')); | 166 test.callbackFail('Failed to connect to the port.')); |
80 }, | 167 }, |
81 | 168 |
| 169 // Test that the correct error message is returned when an error occurs in |
| 170 // calling getPortInfo after connecting to the port. This test uses an |
| 171 // IoHandler that fails on calls to GetPortInfo. |
82 function testGetInfoFailOnConnect() { | 172 function testGetInfoFailOnConnect() { |
83 serial.connect('device', | 173 serial.connect('device', |
84 test.callbackFail('Failed to connect to the port.')); | 174 test.callbackFail('Failed to connect to the port.')); |
85 }, | 175 }, |
86 | 176 |
| 177 // Test that the correct error message is returned when an invalid bit-rate |
| 178 // value is passed to connect. |
87 function testConnectInvalidBitrate() { | 179 function testConnectInvalidBitrate() { |
88 serial.connect('device', {bitrate: -1}, test.callbackFail( | 180 serial.connect('device', {bitrate: -1}, test.callbackFail( |
89 'Failed to connect to the port.')); | 181 'Failed to connect to the port.')); |
90 }, | 182 }, |
91 | 183 |
| 184 // Test that a successful connect returns the expected connection info. |
92 function testConnect() { | 185 function testConnect() { |
93 connect(function(connectionInfo) { | 186 connect(function(connectionInfo) { |
94 disconnect(); | 187 disconnect(); |
95 checkConnectionInfo(connectionInfo); | 188 checkConnectionInfo(connectionInfo); |
96 }); | 189 }); |
97 }, | 190 }, |
98 | 191 |
| 192 // Test that a connection created with no options has the correct default |
| 193 // options. |
99 function testConnectDefaultOptions() { | 194 function testConnectDefaultOptions() { |
100 connect(function(connectionInfo) { | 195 connect(function(connectionInfo) { |
101 disconnect(); | 196 disconnect(); |
102 test.assertEq(9600, connectionInfo.bitrate); | 197 test.assertEq(9600, connectionInfo.bitrate); |
103 test.assertEq('eight', connectionInfo.dataBits); | 198 test.assertEq('eight', connectionInfo.dataBits); |
104 test.assertEq('no', connectionInfo.parityBit); | 199 test.assertEq('no', connectionInfo.parityBit); |
105 test.assertEq('one', connectionInfo.stopBits); | 200 test.assertEq('one', connectionInfo.stopBits); |
106 test.assertFalse(connectionInfo.ctsFlowControl); | 201 test.assertFalse(connectionInfo.ctsFlowControl); |
107 test.assertFalse(connectionInfo.persistent); | 202 test.assertFalse(connectionInfo.persistent); |
108 test.assertEq('', connectionInfo.name); | 203 test.assertEq('', connectionInfo.name); |
109 test.assertEq(0, connectionInfo.receiveTimeout); | 204 test.assertEq(0, connectionInfo.receiveTimeout); |
110 test.assertEq(0, connectionInfo.sendTimeout); | 205 test.assertEq(0, connectionInfo.sendTimeout); |
111 test.assertEq(4096, connectionInfo.bufferSize); | 206 test.assertEq(4096, connectionInfo.bufferSize); |
112 }, {}); | 207 }, {}); |
113 }, | 208 }, |
114 | 209 |
| 210 // Test that a getInfo call correctly converts the service-side info from the |
| 211 // Mojo format and returns both it and the client-side configuration. |
115 function testGetInfo() { | 212 function testGetInfo() { |
116 connect(function() { | 213 connect(function() { |
117 serial.getInfo(connectionId, | 214 serial.getInfo(connectionId, |
118 test.callbackPass(function(connectionInfo) { | 215 test.callbackPass(function(connectionInfo) { |
119 disconnect(); | 216 disconnect(); |
120 checkConnectionInfo(connectionInfo); | 217 checkConnectionInfo(connectionInfo); |
121 })); | 218 })); |
122 }); | 219 }); |
123 }, | 220 }, |
124 | 221 |
| 222 // Test that only client-side options are returned when the service fails a |
| 223 // getInfo call. This test uses an IoHandler that fails GetPortInfo calls |
| 224 // after the initial call during connect. |
125 function testGetInfoFailToGetPortInfo() { | 225 function testGetInfoFailToGetPortInfo() { |
126 connect(function() { | 226 connect(function() { |
127 serial.getInfo(connectionId, | 227 serial.getInfo(connectionId, |
128 test.callbackPass(function(connectionInfo) { | 228 test.callbackPass(function(connectionInfo) { |
129 disconnect(); | 229 disconnect(); |
130 checkClientConnectionInfo(connectionInfo); | 230 checkClientConnectionInfo(connectionInfo); |
131 test.assertFalse('bitrate' in connectionInfo); | 231 test.assertFalse('bitrate' in connectionInfo); |
132 test.assertFalse('dataBits' in connectionInfo); | 232 test.assertFalse('dataBits' in connectionInfo); |
133 test.assertFalse('parityBit' in connectionInfo); | 233 test.assertFalse('parityBit' in connectionInfo); |
134 test.assertFalse('stopBit' in connectionInfo); | 234 test.assertFalse('stopBit' in connectionInfo); |
135 test.assertFalse('ctsFlowControl' in connectionInfo); | 235 test.assertFalse('ctsFlowControl' in connectionInfo); |
136 })); | 236 })); |
137 }); | 237 }); |
138 }, | 238 }, |
139 | 239 |
| 240 // Test that getConnections returns an array containing the open connection. |
140 function testGetConnections() { | 241 function testGetConnections() { |
141 connect(function() { | 242 connect(function() { |
142 serial.getConnections(test.callbackPass(function(connections) { | 243 serial.getConnections(test.callbackPass(function(connections) { |
143 disconnect(); | 244 disconnect(); |
144 test.assertEq(1, connections.length); | 245 test.assertEq(1, connections.length); |
145 checkConnectionInfo(connections[0]); | 246 checkConnectionInfo(connections[0]); |
146 })); | 247 })); |
147 }); | 248 }); |
148 }, | 249 }, |
149 | 250 |
| 251 // Test that getControlSignals correctly converts the Mojo format result. This |
| 252 // test uses an IoHandler that returns values matching the pattern being |
| 253 // tested. |
150 function testGetControlSignals() { | 254 function testGetControlSignals() { |
151 connect(function() { | 255 connect(function() { |
152 var calls = 0; | 256 var calls = 0; |
153 function checkControlSignals(signals) { | 257 function checkControlSignals(signals) { |
154 if (calls == 15) { | 258 if (calls == 15) { |
155 disconnect(); | 259 disconnect(); |
156 } else { | 260 } else { |
157 serial.getControlSignals( | 261 serial.getControlSignals( |
158 connectionId, | 262 connectionId, |
159 test.callbackPass(checkControlSignals)); | 263 test.callbackPass(checkControlSignals)); |
160 } | 264 } |
161 test.assertEq(!!(calls & 1), signals.dcd); | 265 test.assertEq(!!(calls & 1), signals.dcd); |
162 test.assertEq(!!(calls & 2), signals.cts); | 266 test.assertEq(!!(calls & 2), signals.cts); |
163 test.assertEq(!!(calls & 4), signals.ri); | 267 test.assertEq(!!(calls & 4), signals.ri); |
164 test.assertEq(!!(calls & 8), signals.dsr); | 268 test.assertEq(!!(calls & 8), signals.dsr); |
165 calls++; | 269 calls++; |
166 } | 270 } |
167 serial.getControlSignals(connectionId, | 271 serial.getControlSignals(connectionId, |
168 test.callbackPass(checkControlSignals)); | 272 test.callbackPass(checkControlSignals)); |
169 }); | 273 }); |
170 }, | 274 }, |
171 | 275 |
| 276 // Test that setControlSignals correctly converts to the Mojo format result. |
| 277 // This test uses an IoHandler that returns values following the same table of |
| 278 // values as |signalsValues|. |
172 function testSetControlSignals() { | 279 function testSetControlSignals() { |
173 connect(function() { | 280 connect(function() { |
174 var signalsValues = [ | 281 var signalsValues = [ |
175 {}, | 282 {}, |
176 {dtr: false}, | 283 {dtr: false}, |
177 {dtr: true}, | 284 {dtr: true}, |
178 {rts: false}, | 285 {rts: false}, |
179 {dtr: false, rts: false}, | 286 {dtr: false, rts: false}, |
180 {dtr: true, rts: false}, | 287 {dtr: true, rts: false}, |
181 {rts: true}, | 288 {rts: true}, |
182 {dtr: false, rts: true}, | 289 {dtr: false, rts: true}, |
183 {dtr: true, rts: true}, | 290 {dtr: true, rts: true}, |
184 ]; | 291 ]; |
185 var calls = 0; | 292 var calls = 0; |
186 function setControlSignals(success) { | 293 function setControlSignals(success) { |
187 if (calls == signalsValues.length) { | 294 if (calls == signalsValues.length) { |
188 disconnect(); | 295 disconnect(); |
189 } else { | 296 } else { |
190 serial.setControlSignals(connectionId, | 297 serial.setControlSignals(connectionId, |
191 signalsValues[calls++], | 298 signalsValues[calls++], |
192 test.callbackPass(setControlSignals)); | 299 test.callbackPass(setControlSignals)); |
193 } | 300 } |
194 test.assertTrue(success); | 301 test.assertTrue(success); |
195 } | 302 } |
196 setControlSignals(true); | 303 setControlSignals(true); |
197 }); | 304 }); |
198 }, | 305 }, |
199 | 306 |
| 307 // Test that update correctly passes values to the service only for |
| 308 // service-side options and that all update calls are reflected by the result |
| 309 // of getInfo calls. This test uses an IoHandler that expects corresponding |
| 310 // ConfigurePort calls. |
200 function testUpdate() { | 311 function testUpdate() { |
201 connect(function() { | 312 connect(function() { |
202 var optionsValues = [ | 313 var optionsValues = [ |
203 {}, // SetPortOptions is called once during connection. | 314 {}, // SetPortOptions is called once during connection. |
204 {bitrate: 57600}, | 315 {bitrate: 57600}, |
205 {dataBits: 'seven'}, | 316 {dataBits: 'seven'}, |
206 {dataBits: 'eight'}, | 317 {dataBits: 'eight'}, |
207 {parityBit: 'no'}, | 318 {parityBit: 'no'}, |
208 {parityBit: 'odd'}, | 319 {parityBit: 'odd'}, |
209 {parityBit: 'even'}, | 320 {parityBit: 'even'}, |
(...skipping 23 matching lines...) Expand all Loading... |
233 test.callbackPass(function(success) { | 344 test.callbackPass(function(success) { |
234 serial.getInfo(connectionId, test.callbackPass(checkInfo)); | 345 serial.getInfo(connectionId, test.callbackPass(checkInfo)); |
235 test.assertTrue(success); | 346 test.assertTrue(success); |
236 })); | 347 })); |
237 } | 348 } |
238 } | 349 } |
239 setOptions(); | 350 setOptions(); |
240 }); | 351 }); |
241 }, | 352 }, |
242 | 353 |
| 354 // Test that passing an invalid bit-rate reslts in an error. |
243 function testUpdateInvalidBitrate() { | 355 function testUpdateInvalidBitrate() { |
244 connect(function() { | 356 connect(function() { |
245 serial.update(connectionId, | 357 serial.update(connectionId, |
246 {bitrate: -1}, | 358 {bitrate: -1}, |
247 test.callbackPass(function(success) { | 359 test.callbackPass(function(success) { |
248 disconnect(); | 360 disconnect(); |
249 test.assertFalse(success); | 361 test.assertFalse(success); |
250 })); | 362 })); |
251 }); | 363 }); |
252 }, | 364 }, |
253 | 365 |
| 366 // Test flush. This test uses an IoHandler that counts the number of flush |
| 367 // calls. |
254 function testFlush() { | 368 function testFlush() { |
255 connect(function() { | 369 connect(function() { |
256 serial.flush(connectionId, | 370 serial.flush(connectionId, test.callbackPass(function(success) { |
257 test.callbackPass(function(success) { | |
258 disconnect(); | 371 disconnect(); |
259 test.assertTrue(success); | 372 test.assertTrue(success); |
260 })); | 373 })); |
261 }); | 374 }); |
262 }, | 375 }, |
263 | 376 |
| 377 // Test that setPaused values are reflected by the results returned by getInfo |
| 378 // calls. |
264 function testSetPaused() { | 379 function testSetPaused() { |
265 connect(function() { | 380 connect(function() { |
266 serial.setPaused(connectionId, true, test.callbackPass(function() { | 381 serial.setPaused(connectionId, true, test.callbackPass(function() { |
267 serial.getInfo(connectionId, test.callbackPass(function(info) { | 382 serial.getInfo(connectionId, test.callbackPass(function(info) { |
268 serial.setPaused(connectionId, false, test.callbackPass(function() { | 383 serial.setPaused(connectionId, false, test.callbackPass(function() { |
269 serial.getInfo(connectionId, test.callbackPass(function(info) { | 384 serial.getInfo(connectionId, test.callbackPass(function(info) { |
270 test.assertFalse(info.paused); | 385 test.assertFalse(info.paused); |
271 disconnect(); | 386 disconnect(); |
272 })); | 387 })); |
273 })); | 388 })); |
274 test.assertTrue(info.paused); | 389 test.assertTrue(info.paused); |
275 })); | 390 })); |
276 })); | 391 })); |
277 }); | 392 }); |
278 }, | 393 }, |
279 | 394 |
| 395 // Test that a send and a receive correctly echoes data. This uses an |
| 396 // IoHandler that echoes data sent to it. |
| 397 function testEcho() { |
| 398 connect(function() { |
| 399 sendData().then(test.callbackPass(function(sendInfo) { |
| 400 test.assertEq(4, sendInfo.bytesSent); |
| 401 test.assertEq(undefined, sendInfo.error); |
| 402 })); |
| 403 test.listenOnce(serial.onReceive, function(result) { |
| 404 checkReceivedData(result); |
| 405 disconnect(); |
| 406 }); |
| 407 }); |
| 408 }, |
| 409 |
| 410 // Test that a send while another send is in progress returns a pending error. |
| 411 function testSendDuringExistingSend() { |
| 412 connect(function() { |
| 413 sendData().then(test.callbackPass(function(sendInfo) { |
| 414 test.assertEq(4, sendInfo.bytesSent); |
| 415 test.assertEq(undefined, sendInfo.error); |
| 416 disconnect(); |
| 417 })); |
| 418 sendData().then(test.callbackPass(function(sendInfo) { |
| 419 test.assertEq(0, sendInfo.bytesSent); |
| 420 test.assertEq('pending', sendInfo.error); |
| 421 })); |
| 422 }); |
| 423 }, |
| 424 |
| 425 // Test that a second send after the first finishes is successful. This uses |
| 426 // an IoHandler that echoes data sent to it. |
| 427 function testSendAfterSuccessfulSend() { |
| 428 connect(function() { |
| 429 sendData().then(test.callbackPass(function(sendInfo) { |
| 430 test.assertEq(4, sendInfo.bytesSent); |
| 431 test.assertEq(undefined, sendInfo.error); |
| 432 return sendData(); |
| 433 })).then(test.callbackPass(function(sendInfo) { |
| 434 test.assertEq(4, sendInfo.bytesSent); |
| 435 test.assertEq(undefined, sendInfo.error); |
| 436 })); |
| 437 // Check that the correct data is echoed twice. |
| 438 test.listenOnce(serial.onReceive, function(result) { |
| 439 checkReceivedData(result); |
| 440 test.listenOnce(serial.onReceive, function(result) { |
| 441 checkReceivedData(result); |
| 442 disconnect(); |
| 443 }); |
| 444 }); |
| 445 }); |
| 446 }, |
| 447 |
| 448 // Test that a second send after the first fails is successful. This uses an |
| 449 // IoHandler that returns system_error for only the first send. |
| 450 function testSendPartialSuccessWithError() { |
| 451 connect(function() { |
| 452 sendData().then(test.callbackPass(function(sendInfo) { |
| 453 test.assertEq(2, sendInfo.bytesSent); |
| 454 test.assertEq('system_error', sendInfo.error); |
| 455 return sendData(); |
| 456 })).then(test.callbackPass(function(sendInfo) { |
| 457 test.assertEq(4, sendInfo.bytesSent); |
| 458 test.assertEq(undefined, sendInfo.error); |
| 459 disconnect(); |
| 460 })); |
| 461 }); |
| 462 }, |
| 463 |
| 464 // Test that a timed-out send returns a timeout error and that changing the |
| 465 // send timeout during a send does not affect its timeout. This test uses an |
| 466 // IoHandle that never completes sends. |
| 467 function testSendTimeout() { |
| 468 connect(function() { |
| 469 sendData().then(test.callbackPass(function(sendInfo) { |
| 470 test.assertEq(0, sendInfo.bytesSent); |
| 471 test.assertEq('timeout', sendInfo.error); |
| 472 test.assertEq(5, timeoutManager.currentTime); |
| 473 disconnect(); |
| 474 })); |
| 475 serial.update(connectionId, {sendTimeout: 10}, test.callbackPass( |
| 476 timeoutManager.run.bind(timeoutManager, 1))); |
| 477 }, {sendTimeout: 5}); |
| 478 }, |
| 479 |
| 480 // Test that a timed-out send returns a timeout error and that disabling the |
| 481 // send timeout during a send does not affect its timeout. This test uses an |
| 482 // IoHandle that never completes sends. |
| 483 function testDisableSendTimeout() { |
| 484 connect(function() { |
| 485 sendData().then(test.callbackPass(function(sendInfo) { |
| 486 test.assertEq(0, sendInfo.bytesSent); |
| 487 test.assertEq('timeout', sendInfo.error); |
| 488 test.assertEq(6, timeoutManager.currentTime); |
| 489 disconnect(); |
| 490 })); |
| 491 serial.update(connectionId, {sendTimeout: 0}, test.callbackPass( |
| 492 timeoutManager.run.bind(timeoutManager, 1))); |
| 493 }, {sendTimeout: 6}); |
| 494 }, |
| 495 |
| 496 // Test that data received while the connection is paused is queued and |
| 497 // dispatched once the connection is unpaused. |
| 498 function testPausedReceive() { |
| 499 // Wait until the receive hook is installed, then start the test. |
| 500 addReceiveHook(function() { |
| 501 // Unpause the connection after the connection has queued the received |
| 502 // data to ensure the queued data is dispatched when the connection is |
| 503 // unpaused. |
| 504 serial.setPaused(connectionId, false, test.callbackPass()); |
| 505 // Check that setPaused(false) is idempotent. |
| 506 serial.setPaused(connectionId, false, test.callbackPass()); |
| 507 }).then(function() { |
| 508 connect(function() { |
| 509 // Check that setPaused(true) is idempotent. |
| 510 serial.setPaused(connectionId, true, test.callbackPass()); |
| 511 serial.setPaused(connectionId, true, test.callbackPass()); |
| 512 }); |
| 513 }); |
| 514 test.listenOnce(serial.onReceive, function(result) { |
| 515 checkReceivedData(result); |
| 516 disconnect(); |
| 517 }); |
| 518 }, |
| 519 |
| 520 // Test that a receive error received while the connection is paused is queued |
| 521 // and dispatched once the connection is unpaused. |
| 522 function testPausedReceiveError() { |
| 523 addReceiveErrorHook(function() { |
| 524 // Unpause the connection after the connection has queued the receive |
| 525 // error to ensure the queued error is dispatched when the connection is |
| 526 // unpaused. |
| 527 serial.setPaused(connectionId, false, test.callbackPass()); |
| 528 }).then(test.callbackPass(function() { |
| 529 connect(function() { |
| 530 serial.setPaused(connectionId, true, test.callbackPass()); |
| 531 }); |
| 532 })); |
| 533 |
| 534 test.listenOnce(serial.onReceiveError, function(result) { |
| 535 serial.getInfo(connectionId, test.callbackPass(function(connectionInfo) { |
| 536 disconnect(); |
| 537 test.assertTrue(connectionInfo.paused); |
| 538 })); |
| 539 test.assertEq(connectionId, result.connectionId); |
| 540 test.assertEq('device_lost', result.error); |
| 541 }); |
| 542 serial.onReceive.addListener(function() { |
| 543 test.fail('unexpected onReceive event'); |
| 544 }); |
| 545 }, |
| 546 |
| 547 // Test that receive timeouts trigger after the timeout time elapses and that |
| 548 // changing the receive timeout does not affect a wait in progress. |
| 549 function testReceiveTimeout() { |
| 550 connect(function() { |
| 551 test.listenOnce(serial.onReceiveError, function(result) { |
| 552 test.assertEq(connectionId, result.connectionId); |
| 553 test.assertEq('timeout', result.error); |
| 554 test.assertEq(20, timeoutManager.currentTime); |
| 555 serial.getInfo(connectionId, test.callbackPass( |
| 556 function(connectionInfo) { |
| 557 test.assertFalse(connectionInfo.paused); |
| 558 disconnect(); |
| 559 })); |
| 560 }); |
| 561 // Changing the timeout does not take effect until the current timeout |
| 562 // expires or a receive completes. |
| 563 serial.update(connectionId, {receiveTimeout: 10}, test.callbackPass( |
| 564 timeoutManager.run.bind(timeoutManager, 1))); |
| 565 }, {receiveTimeout: 20}); |
| 566 }, |
| 567 |
| 568 // Test that receive timeouts trigger after the timeout time elapses and that |
| 569 // disabling the receive timeout does not affect a wait in progress. |
| 570 function testDisableReceiveTimeout() { |
| 571 connect(function() { |
| 572 test.listenOnce(serial.onReceiveError, function(result) { |
| 573 test.assertEq(connectionId, result.connectionId); |
| 574 test.assertEq('timeout', result.error); |
| 575 test.assertEq(30, timeoutManager.currentTime); |
| 576 serial.getInfo(connectionId, test.callbackPass( |
| 577 function(connectionInfo) { |
| 578 disconnect(); |
| 579 test.assertFalse(connectionInfo.paused); |
| 580 })); |
| 581 }); |
| 582 // Disabling the timeout does not take effect until the current timeout |
| 583 // expires or a receive completes. |
| 584 serial.update(connectionId, {receiveTimeout: 0}, test.callbackPass( |
| 585 timeoutManager.run.bind(timeoutManager, 1))); |
| 586 }, {receiveTimeout: 30}); |
| 587 }, |
| 588 |
| 589 // Test that a receive error from the service is correctly dispatched. This |
| 590 // test uses an IoHandler that only reports 'disconnected' receive errors. |
| 591 function testReceiveErrorDisconnected() { |
| 592 runReceiveErrorTest('disconnected'); |
| 593 }, |
| 594 |
| 595 // Test that a receive error from the service is correctly dispatched. This |
| 596 // test uses an IoHandler that only reports 'device_lost' receive errors. |
| 597 function testReceiveErrorDeviceLost() { |
| 598 runReceiveErrorTest('device_lost'); |
| 599 }, |
| 600 |
| 601 // Test that a receive from error the service is correctly dispatched. This |
| 602 // test uses an IoHandler that only reports 'system_error' receive errors. |
| 603 function testReceiveErrorSystemError() { |
| 604 runReceiveErrorTest('system_error'); |
| 605 }, |
| 606 |
| 607 // Test that a send error from the service is correctly returned as the send |
| 608 // result. This test uses an IoHandler that only reports 'disconnected' send |
| 609 // errors. |
| 610 function testSendErrorDisconnected() { |
| 611 runSendErrorTest('disconnected'); |
| 612 }, |
| 613 |
| 614 // Test that a send error from the service is correctly returned as the send |
| 615 // result. This test uses an IoHandler that only reports 'system_error' send |
| 616 // errors. |
| 617 function testSendErrorSystemError() { |
| 618 runSendErrorTest('system_error'); |
| 619 }, |
| 620 |
| 621 // Test that disconnect returns the correct error for a connection ID that |
| 622 // does not exist. |
280 function testDisconnectUnknownConnectionId() { | 623 function testDisconnectUnknownConnectionId() { |
281 serial.disconnect(-1, test.callbackFail('Serial connection not found.')); | 624 serial.disconnect(-1, test.callbackFail('Serial connection not found.')); |
282 }, | 625 }, |
283 | 626 |
| 627 // Test that getInfo returns the correct error for a connection ID that does |
| 628 // not exist. |
284 function testGetInfoUnknownConnectionId() { | 629 function testGetInfoUnknownConnectionId() { |
285 serial.getInfo(-1, test.callbackFail('Serial connection not found.')); | 630 serial.getInfo(-1, test.callbackFail('Serial connection not found.')); |
286 }, | 631 }, |
287 | 632 |
| 633 // Test that update returns the correct error for a connection ID that does |
| 634 // not exist. |
288 function testUpdateUnknownConnectionId() { | 635 function testUpdateUnknownConnectionId() { |
289 serial.update(-1, {}, test.callbackFail('Serial connection not found.')); | 636 serial.update(-1, {}, test.callbackFail('Serial connection not found.')); |
290 }, | 637 }, |
291 | 638 |
| 639 // Test that setControlSignals returns the correct error for a connection ID |
| 640 // that does not exist. |
292 function testSetControlSignalsUnknownConnectionId() { | 641 function testSetControlSignalsUnknownConnectionId() { |
293 serial.setControlSignals(-1, {}, test.callbackFail( | 642 serial.setControlSignals(-1, {}, test.callbackFail( |
294 'Serial connection not found.')); | 643 'Serial connection not found.')); |
295 }, | 644 }, |
296 | 645 |
| 646 // Test that getControlSignals returns the correct error for a connection ID |
| 647 // that does not exist. |
297 function testGetControlSignalsUnknownConnectionId() { | 648 function testGetControlSignalsUnknownConnectionId() { |
298 serial.getControlSignals(-1, test.callbackFail( | 649 serial.getControlSignals(-1, test.callbackFail( |
299 'Serial connection not found.')); | 650 'Serial connection not found.')); |
300 }, | 651 }, |
301 | 652 |
| 653 // Test that flush returns the correct error for a connection ID that does not |
| 654 // exist. |
302 function testFlushUnknownConnectionId() { | 655 function testFlushUnknownConnectionId() { |
303 serial.flush(-1, test.callbackFail('Serial connection not found.')); | 656 serial.flush(-1, test.callbackFail('Serial connection not found.')); |
304 }, | 657 }, |
305 | 658 |
| 659 // Test that setPaused returns the correct error for a connection ID that does |
| 660 // not exist. |
306 function testSetPausedUnknownConnectionId() { | 661 function testSetPausedUnknownConnectionId() { |
307 serial.setPaused( | 662 serial.setPaused( |
308 -1, true, test.callbackFail('Serial connection not found.')); | 663 -1, true, test.callbackFail('Serial connection not found.')); |
309 serial.setPaused( | 664 serial.setPaused( |
310 -1, false, test.callbackFail('Serial connection not found.')); | 665 -1, false, test.callbackFail('Serial connection not found.')); |
311 }, | 666 }, |
| 667 |
| 668 // Test that send returns the correct error for a connection ID that does not |
| 669 // exist. |
| 670 function testSendUnknownConnectionId() { |
| 671 var buffer = new ArrayBuffer(1); |
| 672 serial.send(-1, buffer, test.callbackFail('Serial connection not found.')); |
| 673 }, |
312 ], test.runTests, exports); | 674 ], test.runTests, exports); |
OLD | NEW |